diff --git a/LICENCE.TXT b/LICENCE.TXT new file mode 100644 index 0000000..6ea85ae --- /dev/null +++ b/LICENCE.TXT @@ -0,0 +1,367 @@ +$Id: LICENCE.TXT,v 1.2 2004/02/04 17:15:37 roca Exp $ + +This archive includes both a library, MCL, and several applications like +FCAST and FLUTE built on top of MCL. + +The MCL library and the upper applications, including FCAST and FLUTE, are +distributed under a GPL (GNU GENERAL PUBLIC LICENSE) license. The detailed +license text follows. + + +-------------------------------------------------------------------------------- + + +MCL-ALC is Copyright (c) 1999-2004 INRIA - Univ. Paris 6 - All rights reserved +main author/contact: vincent.roca@inrialpes.fr + +MCL-NORM is Copyright (c) 2003-2004 INRIA - All rights reserved +main author/contact: vincent.roca@inrialpes.fr + +FCAST is Copyright (c) 1999-2004 INRIA - Univ. Paris 6 - All rights reserved +main authors/contacts: julien.laboure@inrialpes.fr and vincent.roca@inrialpes.fr + +FLUTE is Copyright (c) 2003-2004 INRIA - All rights reserved +main authors/contacts: christoph.neumann@inrialpes.fr, vincent.roca@inrialpes.fr and julien.laboure@inrialpes.fr + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..c36265e --- /dev/null +++ b/Makefile @@ -0,0 +1,186 @@ +# $Id: Makefile,v 1.9 2005/05/12 16:03:12 moi Exp $ +# +# build everything... + +# We need the GNU make tool, on some systems it is called +# gmake, on others make is an alias to gmake. Choose one... +# +#MAKE = make +MAKE = gmake + + +# A phony target is one that is not really the name of a file. +# Using .PHONY prevents problems when a file/dir of the same name +# already exists as is the case here with alc/norm. + +.PHONY: all +all: alc norm + + +.PHONY: alc +alc: + @echo "--------------------" + @echo "*** MCL-ALC library ***" + @echo "--------------------" + cd src/alc; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} + @echo "--------------------" + @echo "***SDP library ***" + @echo "--------------------" + cd src/sdp_lib/src; ${MAKE} cleanall; ${MAKE} + @echo "--------------------" + @echo "*** FLUTE library ***" + @echo "--------------------" + cd src/flute_lib; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} + @echo "--------------------" + @echo "*** FCAST-ALC tool ***" + @echo "--------------------" + cd fcast; ${MAKE} cleanall_alc; ${MAKE} depend; ${MAKE} alc + @echo "--------------------" + @echo "*** RobCast tool ***" + @echo "--------------------" + cd robcast; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} + @echo "--------------------" + @echo "*** Flute tool ***" + @echo "--------------------" + cd flute; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} all + @echo "--------------------" + @echo "*** mclftp tool ***" + @echo "--------------------" + #cd mclftp; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} + @echo "skipped..." + @echo "--------------------" + @echo "*** ALC validation programs ***" + @echo "--------------------" + cd check/alc; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} + @echo "--------------------" + @echo "*** FLUTE validation programs ***" + @echo "--------------------" + cd check/flute; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} + @echo "done" + + +.PHONY: norm +norm: + @echo "--------------------" + @echo "*** MCL-NORM library ***" + @echo "--------------------" + cd src/norm; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} + @echo "--------------------" + @echo "*** FCAST-NORM tool ***" + @echo "--------------------" + cd fcast; ${MAKE} cleanall_norm; ${MAKE} depend; ${MAKE} norm + @echo "--------------------" + @echo "*** mclftp-NORM tool ***" + @echo "--------------------" + cd mclftp; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} norm + @echo "--------------------" + @echo "*** NORM validation programs ***" + @echo "--------------------" + cd check/norm; ${MAKE} cleanall; ${MAKE} depend; ${MAKE} + @echo "done" + + +.PHONY: clean +clean: + @echo "--------------------" + @echo "*** Cleaning MCL-ALC library ***" + @echo "--------------------" + cd src/alc; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning FLUTE library ***" + @echo "--------------------" + cd src/flute_lib; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning MCL-NORM library ***" + @echo "--------------------" + cd src/norm; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning FCAST tool ***" + @echo "--------------------" + cd fcast; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning RobCast tool ***" + @echo "--------------------" + cd robcast; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning Flute tool ***" + @echo "--------------------" + cd flute; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning SDP library ***" + @echo "--------------------" + cd src/sdp_lib/src; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning mclftp tool ***" + @echo "--------------------" + cd mclftp; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning ALC validation programs ***" + @echo "--------------------" + cd check/alc; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning FLUTE validation programs ***" + @echo "--------------------" + cd check/flute; ${MAKE} clean + @echo "--------------------" + @echo "*** Cleaning NORM validation programs ***" + @echo "--------------------" + cd check/norm; ${MAKE} clean + @echo "done" + + +.PHONY: cleanall +cleanall: + @echo "--------------------" + @echo "*** Cleaning MCL-ALC library ***" + @echo "--------------------" + cd src/alc; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning FLUTE library ***" + @echo "--------------------" + cd src/flute_lib; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning MCL-NORM library ***" + @echo "--------------------" + cd src/norm; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning FCAST tool ***" + @echo "--------------------" + cd fcast; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning RobCast tool ***" + @echo "--------------------" + cd robcast; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning SDP library ***" + @echo "--------------------" + cd src/sdp_lib/src; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning Flute tool ***" + @echo "--------------------" + cd flute; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning mclftp tool ***" + @echo "--------------------" + cd mclftp; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning ALC validation programs ***" + @echo "--------------------" + cd check/alc; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning FLUTE validation programs ***" + @echo "--------------------" + cd check/flute; ${MAKE} cleanall + @echo "--------------------" + @echo "*** Cleaning NORM validation programs ***" + @echo "--------------------" + cd check/norm; ${MAKE} cleanall + @echo "*** Cleaning ALC doxygen documents ***" + @echo "--------------------" + cd doc/doxygen/alc; rm html/*.html; rm -rf man/man3/*.3 + @echo "*** Cleaning NORM doxygen documents ***" + @echo "--------------------" + cd doc/doxygen/norm; rm html/*.html; rm -rf man/man3/*.3 + @echo "done" + +# DO NOT DELETE diff --git a/Makefile.common b/Makefile.common new file mode 100644 index 0000000..21a8c4a --- /dev/null +++ b/Makefile.common @@ -0,0 +1,123 @@ +# $Id: Makefile.common,v 1.12 2005/03/23 14:05:00 roca Exp $ +# +# Makefile common declarations +# Edit as appropriate... +# + +# WARNING: "ifeq" is a GNU gmake instruction! +# On solaris 2.X, using /usr/ccs/bin/make instead creates an error: +# "Unexpected end of line seen" + +###### OS Dependant Variables ###### + +# edit as appropriate... + +# Which OS ? +# +# automatic system detection... +# NB: command shell replaces back quotes of script shells +# +SYSTEM = $(shell uname -s) +ifeq (${SYSTEM},Linux) + OS = linux +endif +ifeq (${SYSTEM},SunOS) + OS = solaris +endif +ifeq (${SYSTEM},FreeBSD) + OS = freebsd +endif +ifeq (${SYSTEM},AIX) + OS = aix +endif +ifeq (${SYSTEM},HP-UX) + OS = hp-ux +endif +ifeq (${SYSTEM},IRIX64) + OS = irix +endif +# +# and the old way (e.g. if the above lines do not work!) +# +#OS = linux +#OS = solaris +#OS = freebsd +#OS = aix +#OS = hp-ux +#OS = irix + + +# OS specific variables and tools +# +ifeq (${OS},linux) + OSFLAGS = -DLINUX + # Which compiler? + # NB: use -Wall for compilation warnings with gcc + # + CC = g++ -Wall + LD = g++ -Wall + # IA-64 + #CC = ecc -Wall + #LD = ecc -Wall + # INSURE + #CC = /softs/stow/insure++-6.1.3/bin.linux2/insure + #LD = /softs/stow/insure++-6.1.3/bin.linux2/insure + #CC = /softs/stow/insure++-7.0/bin.linux2/insure + #LD = /softs/stow/insure++-7.0/bin.linux2/insure + # ARM + #CC = /usr/local/arm/bin/arm-linux-g++ + #LD = /usr/local/arm/bin/arm-linux-g++ +endif +ifeq (${OS},solaris) + # NB: __EXTENSIONS__ needed by Solaris 2.5.1 + # OSFLAGS = -DSOLARIS -D__EXTENSIONS__ + OSFLAGS = -DSOLARIS + # Which compiler? + # Prefer SUN's compiler (gcc created problems with readdir + # because of confusions with the UCB readdir version) + # + CC = /opt/SUNWspro/bin/CC + LD = /opt/SUNWspro/bin/CC + #CC = g++ + #LD = g++ +endif +ifeq (${OS},freebsd) + OSFLAGS = -DFREEBSD -I/usr/include/g++ -I/usr/include/c++/3.3 + # Which compiler? + # NB: use -Wall for compilation warnings with gcc + # + CC = g++ -Wall + LD = g++ -Wall +endif +ifeq (${OS},AIX) + OSFLAGS = -DAIX + # Which compiler? + # NB: use -Wall for compilation warnings with gcc + # + CC = g++ -Wall + LD = g++ -Wall +endif +ifeq (${OS},HP-UX) + OSFLAGS = -DHP-UX + # Which compiler? + # NB: use -Wall for compilation warnings with gcc + # + CC = g++ -Wall + LD = g++ -Wall +endif +ifeq (${OS},IRIX) + OSFLAGS = -DIRIX + # Which compiler? + # NB: use -Wall for compilation warnings with gcc + # + CC = g++ -Wall + LD = g++ -Wall +endif + +# Which associated tools ? +AR = ar +#AR = /usr/local/arm/bin/arm-linux-ar +RANLIB = ranlib +#RANLIB = /usr/local/arm/bin/arm-linux-ranlib +DEPEND = makedepend + diff --git a/README b/README new file mode 100644 index 0000000..58edf96 --- /dev/null +++ b/README @@ -0,0 +1,295 @@ + $Id: README,v 1.11 2004/12/21 14:46:28 roca Exp $ + + ---------------------------------------------------------- + MCLv3: an Implementation of the ALC and NORM + Protocols for Reliable and Scalable Multicast Distribution + + README - Vincent Roca and Julien Laboure + ---------------------------------------------------------- + + +1- CONTENTS +----------- + + This archive is composed of: + + - bin/* the binary directory... This is where the binaries + and the MCLv3 library are put. + - doc the documentation and FAQ. + - man the manuals of the MCLv3 API and the various + applications provided. + - src the source directory. There is a sub-directory + for ALC, another one for NORM, and a common + sub-directory for common source and header files. + In particular this is where the API header file + src/common/mcl_lib_api.h is located. + - check/* automatic validation tools. There is a sub-directory + for ALC and another one for NORM. Tests are made + for the MCLv3 ALC/NORM library and for applications. + - fcast(n) the multicast file transfer tool using either the ALC + or NORM reliable multicast protocols. + The binaries of the two versions are distinguished by + their name in the binary directory: + fcast => ALC, fcastn => NORM. + See doc/FAQ.txt for more information on when to + use Flute versus FCAST. + - flute the standardized file delivery tool over ALC + (see RFC 3926). + See doc/FAQ.txt for more information on when to + use Flute versus FCAST. + - mclftp a quick and dirty application used to test some + specificities of MCL. In general, you NEVER use it, + but FCAST instead. + - robcast a simple example of client/server application that + is tolerant to any client or server reboot. This + sample tool, based on ALC, can be the basis of a + more complex, extremely robust client/server + application. + + The main features supported in the various releases are documented + in file: + doc/RELEASE_NOTES + + +2- SUPPORTED OPERATING SYSTEMS +------------------------------ + + Several OS/Platforms are supported + - PC/Linux (only tested on recent FedoraCore/Mandrake distributions) + - Sun/Solaris 2.8 + - PC/Windows XP + - PC/FreeBSD + + Porting MCLv3 to another Unix platforms should not be too difficult + (we are using standard POSIX syscalls), but we didn't try... + + +3- TO CREATE/INSTALL THE TOOLS UNDER UNIX +----------------------------------------- + + A single general Makefile.common file defines the target operating + system and is included by ALL the Makefiles. + In theory EVERYTHING IS AUTOMATIC, but if required you can change + Makefile.common first, e.g. to select the appropriate compiler... + + IMPORTANT: our Makefiles require the use of the GNU flavor of the + make command: gmake. + If not available and if you cannot (or don't want) to install gmake, + then edit all makefiles to remove gmake specificities (e.g. inline + the Makefile.common file in all makefiles, remove .phony lines, etc.) + + * To compile everything at once... + + If you use the LDPC large block FEC codec, you must also get + the LDPC archive, untar/unzip it at the same level as MCLv3 + (e.g. mcl_dir/ldpc_v1.X and mcl_dir/mclv3_v3.X). + Then you compile LDPC, which will create the ldpc library: + ${LDPC_BINDIR}/bin//libldpc.a + Then in a second step you can compile MCLv3 as explained below. + + To create atomatically ALL the MCLv3 tools, you can use make at the + top directory. All the directories are crossed and (g)make launched + there. This is the recommanded solution ! + The binaries are automatically put in the bin// directory. + + If you only want to compile ALC (resp. NORM) tools, then type: + make alc (resp. make norm) + at the top directory. + Compiling for ALC produces the fcast (and flute if Xerces-c is + available, see below) tools. + Compiling for NORM produces the fcastn tool only. + + * To compile component by component... + + To compile the library: + - If needed, edit the MCLv3 profile file: + src/[norm|alc]/mcl_profile.h + - From directory src/[norm|alc]/ type: + make clean; make depend; make + + Then compile the application (e.g. fcast) and link + it with the library. From the application directory (e.g. fcast/) + type: + make clean; make depend; + and: + make alc (for the ALC version) + or: + make norm (for the NORM version). + The binaries are automatically put in the bin/OS_DIR/ directory. + + * To compile the Flute tool... + + To compile the Flute tool, Xerces-c must be installed on your host. + http://xml.apache.org/xerces-c + Under non-windows systems you have two choices: + 1) Install Xerces-c as a system library and dynamically link to it: + - Downlowd Xerces-c "Current source release". + - Build Xerces-c as explained in "Build-Instructions" on the + Xerces-c website. + - Don't forget to make a "gmake install" (as root) at the end. + - type "make" (or "make dynamic") in the FLUTE directory + (or "make alc" at the top mclv3 directory, if the ALC version + wasn't compiled before) + + 2) Install Xerces-c as a system library: + - Downlowd Xerces-c "Current source release". + - untar (or unzip) it at the same level as MCLv3. + Rename the xerces-c directory to the name "xerces-c". + - Build Xerces-c as explained in "Build-Instructions" on the + Xerces-c website. + - type "make static" in the FLUTE directory + (a "make alc" at the top mclv3 directory has to be perfomed + before) + + Xerces-c is only required by Flute, so there's no need to install it + if you want to use FCAST (ALC version), or are only interested in + NORM. + + With Solaris 2.8, in order to compile with SUN's C++ compiler, + you may need to add the folowing supported C++ compiler: + *CC + in the following check: + case $cppcompiler in + Then use runConfigure, specifying the SUN compiler, as follows: + runConfigure -psolaris -c/opt/SUNWspro/bin/CC -x/opt/SUNWspro/bin/CC + -minmem -nsocket -tnative -rpthread + + * To validate/check everything... + + Many validation scripts and applications have been written. + Once everything has been compiled, type: + check/[norm|alc]/checkall.sh + Each individual test is run and a report printed. + Note that some tests can be rather long and erroneously give the + impression the system hangs. This is normal. + If one of the tests fails, tell us immediately!!! + + * Remarks + + NB1: The MCLv3 library profile is defined in files + src/[norm|alc]/mcl_profile.h + Edit them as appropriate... + + NB2: If you try to compile MCLv3 but don't have the LDPC archive, + you can run into problems since FCAST and some other applications + will try to link the libldpc.a library (in ${LDPC_BINDIR}/bin//). + Then you can either (1) compile with RSE only and remove the + ${LDPC_BINDIR}/libldpc.a from all makefiles (FCAST, validation...). + Another possibility (2) is to get the LDPC archive and compile it. + In that case, if you only use RSE in MCLv3, no symbol from + libldpc.a will be included, and it will make the compiler happy. + + +4- TO CREATE/INSTALL THE TOOLS UNDER WINDOWS +-------------------------------------------- + + The MCLv3 archive includes a Visual C++ 7(.Net) Solution file (.sln) + to build the library and associated applications. + Compiling the Library using another Windows compiler has not been + tested, but should be possible. + + * To compile... + + If you use the LDPC large block FEC codec, you must also get + the LDPC archive, untar/unzip it at the same level as MCLv3 + (e.g. mcl_dir/ldpc_v1.X and mcl_dir/mclv3_v3.X). + Then you compile LDPC in Visuall C++ 7 (.Net), which will create the + ldpc library: + ${LDPC_BINDIR}/bin/win32/libldpc.a + Then in a second step you can compile MCLv3 as explained below. + + Open The MCLv3 Solution in Visual C++ 7 (.Net) and use the BUILD menu to + create the library and/or the MCLv3 tools (there is one project for + each application). + The binaries are created in the bin/win32/ directory. + + * To compile the Flute tool... + + To compile the Flute tool, Xerces-c must be installed on your host. + http://xml.apache.org/xerces-c + Under Windows: + - Downlowd Xerces-c precompiled binary version for Windows. + - The xerces-c directory must be at the same level + as the MCLv3 directory. + Rename the xerces-c directory to the name "xerces-c". + - Compile MCLv3 with FLUTE. + + Xerces-c is only required by Flute, so there's no need to install it + if you want to use FCAST (ALC version), or are only interested in + NORM. + + * To validate/check everything... + + Validation tools for Windows are in the check/wincheck directory. + The main tool (wincheck) has its own workspace that you should open + with Visual C++ (located in check/wincheck/wincheck.dsw). Once + you've opened it, check that wincheck.dsp is the active project + in the workspace, and then BUILD wincheck.exe (as wincheck has + dependencies, doing this will build everything required, including + the MCLv3 lib and tools). + + Running wincheck.exe will perform a full validation script of the + library, calling different tests. + Each individual test prints a report. + Note that some tests can be rather long and erroneously give the + impression the system hangs. This is normal. + If one of the tests fails, tell us!!! + + * Remarks + + NB1: The profile of the library is defined in file + src/[norm|alc]/mcl_profile.h. Edit it as appropriate... + + +5- TO USE THE TOOLS +------------------- + + For FCAST, FCASTN, and FLUTE applications, type: + fcast[n] -help + or: + flute -help + to see the available parameters. + + There are also manual pages for each tool in the man directory. + Type + man ./flute.man.1 + to read it, or use the html/pdf versions (if not available, + a make pdf or make html in the man directory will build them, + assuming you have the required conversion tools). + + Exemple (more examples in the man pages): + $ flute -send -a225.1.2.3/2323 -v1 -phigh -ospeed file.ps + for the source, and: + $ flute -recv -a225.1.2.3/2323 -v1 -phigh -ospeed -force + for the receiver. + + +NOTES +----- + + The MCLv3 library is distributed under an Open Source / GNU GPL + licence. + FCAST and other applications built on top of MCLv3 are distributed + under an Open Source / GNU GPL licence. + The official copyright and licence is in file LICENCE.TXT. + See the related LICENCE.TXT file for LDPC large block FEC codec + licence information. + + The official MCLv3 web site URL: + http://www.inrialpes.fr/planete/people/roca/mcl/ + + Two (spam free!) moderated mailing lists exist: + mcl-announce@inrialpes.fr to be informed + mcl-bugs@inrialpes.fr to report problems, bugs, + suggestions... + To subscribe, see the official MCLv3 web site. + To unsubscribe, send me an email at: + vincent.roca@inrialpes.fr + + For further informations/comments (or just if you find this tool + interesting ;-) then send me an email at: + vincent.roca@inrialpes.fr + If you have special needs, don't hesitate to ask us, maybe it can + be easily added to the next release... We are also open to any + suggestion, and if you want to help, you're welcome ;-) + diff --git a/check/alc/Makefile b/check/alc/Makefile new file mode 100644 index 0000000..f90a815 --- /dev/null +++ b/check/alc/Makefile @@ -0,0 +1,242 @@ +# $Id: Makefile,v 1.27 2005/02/25 14:13:09 moi Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Makefile.common as appropriate +include ../../Makefile.common + + +# libraries required +ifeq (${OS},linux) + # Linux version + # + BINDIR = ../../bin/linux + LDPC_BINDIR = ../../../ldpc/bin/linux + # Edit the following two lines as appropriate, according to the FEC + # codec in use: if LDPC is used, then add the libbdpc.a library. + # + #LIBRARIES = -lc -lm -lpthread ${BINDIR}/libmclalc.a + LIBRARIES = -lc -lm -lpthread ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +endif + +ifeq (${OS},solaris) + # Solaris version + # + BINDIR = ../../bin/solaris + LDPC_BINDIR = ../../../ldpc/bin/solaris + # Edit the following two lines as appropriate, according to the FEC + # codec in use: if LDPC is used, then add the libbdpc.a library. + # + #LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -mt -lpthread ${BINDIR}/libmclalc.a + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -mt -lpthread ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +endif + +ifeq (${OS},freebsd) + # Linux version + # + BINDIR = ../../bin/freebsd + LDPC_BINDIR = ../../../ldpc/bin/freebsd + # Edit the following two lines as appropriate, according to the FEC + # codec in use: if LDPC is used, then add the libbdpc.a library. + # + LIBRARIES = -lm -pthread ${BINDIR}/libmclalc.a + LIBRARIES = -lm -pthread ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +CFLAGS = -O -g -DALC ${OSFLAGS} + +# cc version +# -fullwarn for IRIX c compiler +#CFLAGS = -O -fullwarn -DALC ${OSFLAGS} + +# add purify linker for memory debug (Solaris only). +# Purify 4.0 Solaris 2, Copyright (C) 1992-1996 Pure Software Inc. +# +#CCLINK_PURE = purify $(CC) +CCLINK_PURE = purify -cache-dir=/tmp $(CC) + + +# List of source and object test files +SRCFILES = test_several_fec_codecs.c test_wait_tx.c test_wait_rx_sender.c test_wait_rx_receiver.c test_no_tx.c test_abort.c test_seq_of_tx_sessions.c test_multi_sessions1.c test_multi_sessions2.c test_demux_label1_tx.c test_demux_label1_rx.c test_demux_label2_tx.c test_demux_label2_rx.c test_dyn_tsi.c test_vtm_tx.c test_vtm_rx.c test_rebootable_client.c test_rebootable_server.c test_reset_transmission.c test_stop_tx_one_adu.c +OFILES = ${SRCFILES:.c=.o} +TARGETS = ${SRCFILES:.c=} + + + +###### Dependancies ###### + +all: ${TARGETS} + +test_several_fec_codecs: test_several_fec_codecs.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_several_fec_codecs.o ${LIBRARIES} -o test_several_fec_codecs + strip test_several_fec_codecs + +test_wait_tx: test_wait_tx.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_wait_tx.o ${LIBRARIES} -o test_wait_tx + strip test_wait_tx + +test_wait_rx_sender: test_wait_rx_sender.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_wait_rx_sender.o ${LIBRARIES} -o test_wait_rx_sender + strip test_wait_rx_sender + +test_wait_rx_receiver: test_wait_rx_receiver.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_wait_rx_receiver.o ${LIBRARIES} -o test_wait_rx_receiver + strip test_wait_rx_receiver + +test_no_tx: test_no_tx.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_no_tx.o ${LIBRARIES} -o test_no_tx + strip test_no_tx + +test_abort: test_abort.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_abort.o ${LIBRARIES} -o test_abort + strip test_abort + +test_seq_of_tx_sessions: test_seq_of_tx_sessions.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_seq_of_tx_sessions.o ${LIBRARIES} -o test_seq_of_tx_sessions + strip test_seq_of_tx_sessions + +test_reset_transmission: test_reset_transmission.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_reset_transmission.o ${LIBRARIES} -o test_reset_transmission + strip test_reset_transmission + +test_stop_tx_one_adu: test_stop_tx_one_adu.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_stop_tx_one_adu.o ${LIBRARIES} -o test_stop_tx_one_adu + strip test_stop_tx_one_adu + + +test_multi_sessions1: test_multi_sessions1.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_multi_sessions1.o ${LIBRARIES} -o test_multi_sessions1 + strip test_multi_sessions1 + +test_multi_sessions2: test_multi_sessions2.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_multi_sessions2.o ${LIBRARIES} -o test_multi_sessions2 + strip test_multi_sessions2 + +test_demux_label1_tx: test_demux_label1_tx.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_demux_label1_tx.o ${LIBRARIES} -o test_demux_label1_tx + strip test_demux_label1_tx + +test_demux_label1_rx: test_demux_label1_rx.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_demux_label1_rx.o ${LIBRARIES} -o test_demux_label1_rx + strip test_demux_label1_rx + +test_demux_label2_tx: test_demux_label2_tx.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_demux_label2_tx.o ${LIBRARIES} -o test_demux_label2_tx + strip test_demux_label2_tx + +test_demux_label2_rx: test_demux_label2_rx.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_demux_label2_rx.o ${LIBRARIES} -o test_demux_label2_rx + strip test_demux_label2_rx + + +test_dyn_tsi: test_dyn_tsi.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_dyn_tsi.o ${LIBRARIES} -o test_dyn_tsi + #strip test_dyn_tsi + +pure: test_dyn_tsi.o ${BINDIR}/libmclalc.a + ${CCLINK_PURE} ${CFLAGS} test_dyn_tsi.o ${LIBRARIES} -o test_dyn_tsi + +test_vtm_tx: test_vtm_tx.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_vtm_tx.o ${LIBRARIES} -o test_vtm_tx + strip test_vtm_tx + +test_vtm_rx: test_vtm_rx.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_vtm_rx.o ${LIBRARIES} -o test_vtm_rx + strip test_vtm_rx + +test_rebootable_client: test_rebootable_client.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_rebootable_client.o ${LIBRARIES} -o test_rebootable_client + strip test_rebootable_client + +test_rebootable_server: test_rebootable_server.o ${BINDIR}/libmclalc.a + ${CC} ${CFLAGS} test_rebootable_server.o ${LIBRARIES} -o test_rebootable_server + strip test_rebootable_server + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in core ${TARGETS} ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +test_several_fec_codecs.o: ../../src/common/mcl_lib_api.h +test_several_fec_codecs.o: ../../src/common/mcl_types.h +test_several_fec_codecs.o: ../../src/alc/mcl_lib_api_alc.h +test_wait_tx.o: ../../src/common/mcl_lib_api.h ../../src/common/mcl_types.h +test_wait_tx.o: ../../src/alc/mcl_lib_api_alc.h +test_wait_rx_sender.o: ../../src/common/mcl_lib_api.h +test_wait_rx_sender.o: ../../src/common/mcl_types.h +test_wait_rx_sender.o: ../../src/alc/mcl_lib_api_alc.h +test_wait_rx_receiver.o: ../../src/common/mcl_lib_api.h +test_wait_rx_receiver.o: ../../src/common/mcl_types.h +test_wait_rx_receiver.o: ../../src/alc/mcl_lib_api_alc.h +test_no_tx.o: ../../src/common/mcl_lib_api.h ../../src/common/mcl_types.h +test_no_tx.o: ../../src/alc/mcl_lib_api_alc.h +test_abort.o: ../../src/common/mcl_lib_api.h ../../src/common/mcl_types.h +test_abort.o: ../../src/alc/mcl_lib_api_alc.h +test_seq_of_tx_sessions.o: ../../src/common/mcl_lib_api.h +test_seq_of_tx_sessions.o: ../../src/common/mcl_types.h +test_seq_of_tx_sessions.o: ../../src/alc/mcl_lib_api_alc.h +test_multi_sessions1.o: ../../src/common/mcl_lib_api.h +test_multi_sessions1.o: ../../src/common/mcl_types.h +test_multi_sessions1.o: ../../src/alc/mcl_lib_api_alc.h +test_multi_sessions2.o: ../../src/common/mcl_lib_api.h +test_multi_sessions2.o: ../../src/common/mcl_types.h +test_multi_sessions2.o: ../../src/alc/mcl_lib_api_alc.h +test_demux_label1_tx.o: ../../src/common/mcl_lib_api.h +test_demux_label1_tx.o: ../../src/common/mcl_types.h +test_demux_label1_tx.o: ../../src/alc/mcl_lib_api_alc.h +test_demux_label1_rx.o: ../../src/common/mcl_lib_api.h +test_demux_label1_rx.o: ../../src/common/mcl_types.h +test_demux_label1_rx.o: ../../src/alc/mcl_lib_api_alc.h +test_demux_label2_tx.o: ../../src/common/mcl_lib_api.h +test_demux_label2_tx.o: ../../src/common/mcl_types.h +test_demux_label2_tx.o: ../../src/alc/mcl_lib_api_alc.h +test_demux_label2_rx.o: ../../src/common/mcl_lib_api.h +test_demux_label2_rx.o: ../../src/common/mcl_types.h +test_demux_label2_rx.o: ../../src/alc/mcl_lib_api_alc.h +test_dyn_tsi.o: ../../src/common/mcl_lib_api.h ../../src/common/mcl_types.h +test_dyn_tsi.o: ../../src/alc/mcl_lib_api_alc.h +test_vtm_tx.o: ../../src/common/mcl_lib_api.h ../../src/common/mcl_types.h +test_vtm_tx.o: ../../src/alc/mcl_lib_api_alc.h +test_vtm_rx.o: ../../src/common/mcl_lib_api.h ../../src/common/mcl_types.h +test_vtm_rx.o: ../../src/alc/mcl_lib_api_alc.h +test_rebootable_client.o: ../../src/common/mcl_lib_api.h +test_rebootable_client.o: ../../src/common/mcl_types.h +test_rebootable_client.o: ../../src/alc/mcl_lib_api_alc.h +test_rebootable_server.o: ../../src/common/mcl_lib_api.h +test_rebootable_server.o: ../../src/common/mcl_types.h +test_rebootable_server.o: ../../src/alc/mcl_lib_api_alc.h +test_reset_transmission.o: ../../src/common/mcl_lib_api.h +test_reset_transmission.o: ../../src/common/mcl_types.h +test_reset_transmission.o: ../../src/alc/mcl_lib_api_alc.h +test_stop_tx_one_adu.o: ../../src/common/mcl_lib_api.h +test_stop_tx_one_adu.o: ../../src/common/mcl_types.h +test_stop_tx_one_adu.o: ../../src/alc/mcl_lib_api_alc.h diff --git a/check/alc/checkall.sh b/check/alc/checkall.sh new file mode 100755 index 0000000..98dfa2a --- /dev/null +++ b/check/alc/checkall.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# $Id: checkall.sh,v 1.2 2004/12/21 14:43:44 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# top validation script +# +# scans and executes all the elementary test scripts contained in this dir +# + +test_sh_list=`ls test_*.sh` # sh scripts +test_pl_list=`ls test_*.pl` # perl scripts + + +for t in ${test_sh_list} ${test_pl_list} ; do + echo "" + echo "" + echo "------> Running test ${t}" + ./${t} + val=$? + + if [ ${val} -ne 0 ] ; then + echo "" + echo "****** ERROR: Test ${t} failed! Aborting... ******" + exit + fi + echo "<------ Test ${t} passed" +done +echo "" +echo "" +echo "****** All tests succeeded! Validation OK ******" + diff --git a/check/alc/fcast_test/recv/Other_Files/i-am-a-BIG.file b/check/alc/fcast_test/recv/Other_Files/i-am-a-BIG.file new file mode 100755 index 0000000..8366245 --- /dev/null +++ b/check/alc/fcast_test/recv/Other_Files/i-am-a-BIG.file @@ -0,0 +1,64 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" \ No newline at end of file diff --git a/check/alc/fcast_test/send/0_Byte_File b/check/alc/fcast_test/send/0_Byte_File new file mode 100644 index 0000000..e69de29 diff --git a/check/alc/fcast_test/send/2_Bytes_File b/check/alc/fcast_test/send/2_Bytes_File new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/check/alc/fcast_test/send/2_Bytes_File @@ -0,0 +1 @@ +2 diff --git a/check/alc/fcast_test/send/3_Bytes_File b/check/alc/fcast_test/send/3_Bytes_File new file mode 100644 index 0000000..ff3eb13 --- /dev/null +++ b/check/alc/fcast_test/send/3_Bytes_File @@ -0,0 +1 @@ +3! diff --git a/check/alc/fcast_test/send/4_Bytes_File b/check/alc/fcast_test/send/4_Bytes_File new file mode 100644 index 0000000..1e6fd03 --- /dev/null +++ b/check/alc/fcast_test/send/4_Bytes_File @@ -0,0 +1 @@ +444 diff --git a/check/alc/fcast_test/send/Other_Files/i-am-a-BIG.file b/check/alc/fcast_test/send/Other_Files/i-am-a-BIG.file new file mode 100644 index 0000000..8366245 --- /dev/null +++ b/check/alc/fcast_test/send/Other_Files/i-am-a-BIG.file @@ -0,0 +1,64 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" \ No newline at end of file diff --git a/check/alc/fcast_test/send/Other_Files/i-am-a.file b/check/alc/fcast_test/send/Other_Files/i-am-a.file new file mode 100644 index 0000000..753cf7a --- /dev/null +++ b/check/alc/fcast_test/send/Other_Files/i-am-a.file @@ -0,0 +1,95 @@ +# $Id: i-am-a.file,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Rules.mk + + +# libraries required +ifeq (${OS},linux) + # Linux version + # MCL library requires -lpthread + # + BINDIR = ../bin/linux + LIBRARIES = -lc -lm -lpthread ${BINDIR}/libmcl.a +endif + +ifeq (${OS},solaris) + # Solaris version: requires -lsocket -lnsl and -L/usr/ucblib -lucb + # + BINDIR = ../bin/solaris + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -lpthread ${BINDIR}/libmcl.a +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +CFLAGS = -O -g ${OSFLAGS} + +# cc version +# -fullwarn for IRIX c compiler +#CFLAGS = -O -fullwarn ${OSFLAGS} + +SRCFILES = test_no_tx.c +OFILES = test_no_tx.o +TARGETS = test_no_tx + + +###### Dependancies ###### + +all: ${TARGETS} + +test_no_tx: test_no_tx.o ${BINDIR}/libmcl.a + ${CC} ${CFLAGS} test_no_tx.o ${LIBRARIES} -o test_no_tx + strip test_no_tx + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in core ${TARGETS} ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # use -p to say that objects are in the bin dir + # ${DEPEND} -pbin/ -- ${CFLAGS} -- ${SRCFILES} + ${DEPEND} -- ${CFLAGS} -- ${SRCFILES} + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +test_no_tx.o: /usr/include/stdio.h /usr/include/features.h +test_no_tx.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +test_no_tx.o: /usr/include/bits/types.h /usr/include/libio.h +test_no_tx.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +test_no_tx.o: /usr/include/netinet/in.h /usr/include/limits.h +test_no_tx.o: /usr/include/bits/posix1_lim.h /usr/include/bits/local_lim.h +test_no_tx.o: /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h +test_no_tx.o: /usr/include/stdint.h /usr/include/bits/wordsize.h +test_no_tx.o: /usr/include/sys/types.h /usr/include/time.h +test_no_tx.o: /usr/include/endian.h /usr/include/bits/endian.h +test_no_tx.o: /usr/include/sys/select.h /usr/include/bits/select.h +test_no_tx.o: /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h +test_no_tx.o: /usr/include/bits/socket.h /usr/include/bits/sockaddr.h +test_no_tx.o: /usr/include/asm/socket.h /usr/include/asm/sockios.h +test_no_tx.o: /usr/include/bits/in.h /usr/include/bits/byteswap.h +test_no_tx.o: ../src/mcl_lib.h diff --git a/check/alc/test_abort b/check/alc/test_abort new file mode 100755 index 0000000..06f3a4b Binary files /dev/null and b/check/alc/test_abort differ diff --git a/check/alc/test_abort.c b/check/alc/test_abort.c new file mode 100644 index 0000000..af46bc6 --- /dev/null +++ b/check/alc/test_abort.c @@ -0,0 +1,146 @@ +/* $Id: test_abort.c,v 1.2 2004/02/24 16:57:26 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_abort.c + */ + +#include +#include /* for exit */ + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#include /* for sleep */ +#endif /* OS_DEP */ + +#include "../../src/common/mcl_lib_api.h" + + +#define BUFLEN 2400 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id = 0; + int port = 2324; + unsigned long addr = ntohl(inet_addr("230.1.2.3")); + int verbose = VERBOSITY; + char buf[BUFLEN]; + int err; + + printf("test_abort: open(w)/send/abort\n"); + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } + if (port > 0) { /* in host format! */ + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed\n"); + exit(-1); + } + } + if (addr > 0) { /* in host format! */ + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed\n"); + exit(-1); + } + } + if (verbose > 0) { + err = mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, + sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed\n"); + exit(-1); + } + } + err = mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + if ((err = mcl_send(id, buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed\n"); + exit(-1); + } + if ((err = mcl_abort(id)) < 0) { + printf("ERROR: mcl_abort failed\n"); + exit(-1); + } + printf("... ok\n"); + + printf("******\n"); + printf("test_abort: open(w)/abort\n"); + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } + if (port > 0) { /* in host format! */ + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed\n"); + exit(-1); + } + } + if (addr > 0) { /* in host format! */ + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed\n"); + exit(-1); + } + } + if (verbose > 0) { + err = mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, + sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed\n"); + exit(-1); + } + } + if ((err = mcl_abort(id)) < 0) { + printf("ERROR: mcl_abort failed\n"); + exit(-1); + } + printf("... ok\n"); +#ifdef WIN32 + _sleep(1000); /* for the wait pid in test_no_tx.sh to work properly */ +#else + sleep(1); /* for the wait pid in test_no_tx.sh to work properly */ +#endif + + return(0); +} + diff --git a/check/alc/test_abort.sh b/check/alc/test_abort.sh new file mode 100755 index 0000000..9ec6285 --- /dev/null +++ b/check/alc/test_abort.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# +# $Id: test_abort.sh,v 1.2 2004/12/21 14:43:44 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test the MCL with an application that opens/sends/aborts + +./test_abort +val=$? + +echo "returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +else + exit 0 +fi + diff --git a/check/alc/test_bad_pkt.c b/check/alc/test_bad_pkt.c new file mode 100644 index 0000000..95b0c88 --- /dev/null +++ b/check/alc/test_bad_pkt.c @@ -0,0 +1,811 @@ +/* $Id: test_bad_pkt.c,v 1.1.1.1 2003/09/03 12:45:37 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ +/* author: Zainab KHALLOUF */ + +#define _C_TEST + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "test_bad_pkt.h" + +#define MAXLEN 1024 +#define TTL 1 + +/*-------------------------------------------------------------------------*/ +/* + * buffer dump + */ +void +DumpBuffer (char *buf, + int len, + int to_dump) /* number of u32 words to dump */ +{ + int i, j; + int *ptr; + + i = min(to_dump, (len >> 2)); + j = 0; + PRINT_OUT((stdout, "\tDUMP %d first bytes... (len=%d/dump=%d)\n\t", + i * sizeof(int), + len, to_dump)) + for (ptr = (int*)buf; i > 0; i--, ptr++) { + /* convert to network format to be sure of byte order */ + PRINT_OUT((stdout, "%08x ",htonl(*ptr))); + + if (++j == 8) { + j = 0; + PRINT_OUT((stdout, "\n\t")) + } + } + PRINT_OUT((stdout, "\n")) +} +/*-------------------------------------------------------------------------*/ +int lct_fixed_hdr_create + (u_int16_t v ,/* LCT version Number */ + u_int16_t d ,/* Demux Label Present flag */ + u_int16_t r ,/* reserved; must be zero in the sender*/ + u_int16_t t ,/* Transm Extension Info Present flag */ + u_int16_t x ,/* Header-extension fields flag */ + + lct_infos_t *lct_infos , + fixed_lct_hdr_t *lct_hdr , + int hlen , /*initial value for HDR_LEN, necessair + for the test TEST_HDR_LEN*/ + + + u_int32_t sctTime,/*Sender current time in ms*/ + u_int32_t ertTime,/*ERT in ms*/ + int add_dl_flag ,/*to add a DL field*/ + int add_sct_ert_flag ,/*to add a SCT,ERT fields*/ + + + int add_he_toi_flag ,/*to add a header extension TOI */ + + int add_he_fpi_flag ,/*to add a header extension FPI (forword + *error correction payload identifier)*/ + + int add_he_fti_flag ,/*to add a header extension FTI(forward + *error correction object transmission + *identifier)*/ + + int he_type ,/*to add header extension witch type not + listed in the draft necessair for the + test TEST_NOT_EXT*/ + + int hel_he_toi ,/*header extension length*/ + int last_he_flag ,/*L in the last header extension must be 1 + *last_he_flag = 1 <=> L=1 in + *all header extension + *last_he_flag = 0 <=> L=0 in + *all header extension + *last_he_flag = 2 <=> L=1 in + *the last header extension */ + + + int reverse_flag , /*to add header extension FPI before + the header extension TOI*/ + + int nop_flag) /*Add Header extension NOP before the header + extension TOI,Suivant the draft the receiver + must ignore the information in this field*/ + + + +{ + u_int32_t *last_ext = NULL; + int L=0 ;/*Flag in the last header extension*/ + + lct_hdr->version = v &0x3; + lct_hdr->flag_d = d & 0x1; + lct_hdr->reserved= r & 0x1; + lct_hdr->flag_t = t & 0x1; + lct_hdr->flag_x = x & 0x1; + lct_hdr->toi = ((lct_infos->idf_toi) & 0x3ff); + lct_hdr->codepoint = ((lct_infos->codepoint)& 0xff); + lct_hdr->cci = htonl((lct_infos->cci_idf) & 0xffffffff); + /*--------------------------------------------------------*/ + /*length of fixed and variable part of lct header*/ + hlen = hlen + sizeof(fixed_lct_hdr_t); + if ((lct_infos->demux_label)&& (add_dl_flag)) { + /* add a demux label */ + hlen=lct_hdr_add_DL((char*)lct_hdr,hlen,lct_infos->demux_label); + if (hlen < 0) goto bad; + } + /*--------------------------------------------------------*/ + if (add_sct_ert_flag){ + hlen =lct_hdr_add_sct_ert ((char*)lct_hdr,hlen,sctTime,ertTime); + if (hlen < 0) goto bad; + + } + if (last_he_flag == 2) L=1; + + /*--------------------------------------------------------*/ + + if (nop_flag){ + /* add an NOP EXT */ + last_ext = (u_int32_t*)((char*)lct_hdr+hlen);/* to add L bit */ + hlen=lct_hdr_add_NOP_he((char*)lct_hdr, hlen, lct_infos,L); + if (hlen < 0) goto bad; + } + + if (reverse_flag) + { + if ((lct_infos->payload_id_present)&&(add_he_fpi_flag)) { + /* add an FPI (FEC payload idf) extension (required if data) */ + last_ext = (u_int32_t*)((char*)lct_hdr+hlen);/* to add L bit */ + hlen = lct_hdr_add_FPI_he((char*)lct_hdr, hlen, lct_infos,L); + if (hlen < 0) goto bad; + } + + if (((lct_infos->idf_toi)> 1023) && (add_he_toi_flag)){ + last_ext = (u_int32_t*)((char*)lct_hdr+hlen);/* To add L bit */ + hlen = lct_hdr_add_TOI_he((char*)lct_hdr,hlen,he_type, + hel_he_toi,lct_infos,L); + if (hlen < 0) goto bad; + lct_hdr->toi = 0; + } + + } + else/*Normal case*/ + { + if (((lct_infos->idf_toi)> 1023) && (add_he_toi_flag)){ + last_ext = (u_int32_t*)((char*)lct_hdr+hlen);/* To add L bit */ + + hlen = lct_hdr_add_TOI_he((char*)lct_hdr,hlen,he_type, + hel_he_toi,lct_infos,L); + + if (hlen < 0) goto bad; + lct_hdr->toi = 0; + } + + if ((lct_infos->payload_id_present)&&(add_he_fpi_flag)) { + /* add an FPI (FEC payload idf) extension (required if data) */ + last_ext = (u_int32_t*)((char*)lct_hdr+hlen);/* to add L bit */ + hlen = lct_hdr_add_FPI_he((char*)lct_hdr, hlen, lct_infos,L); + if (hlen < 0) goto bad; + } + }//reverse_flag + + if ((lct_infos->adu_len > 0)&&(add_he_fti_flag)) { + /* add an FTI (FEC objet tx idf) extension */ + last_ext = (u_int32_t*)((char*)lct_hdr+hlen);/* to add L bit */ + hlen = lct_hdr_add_FTI_he((char*)lct_hdr, hlen, lct_infos,L); + if (hlen < 0) goto bad; + } + + /*--------------------------------------------------------*/ + if (last_ext){lct_hdr->flag_x= 1;} + if ((last_he_flag==2)&&(last_ext)) /*L=1 in the last header extension */ + { + u_int32_t add_L; + add_L = ntohl(*last_ext); + add_L |= 0x80000000; + *last_ext = htonl(add_L);} + + lct_hdr->hdr_len =(hlen - 8) >> 2; /*in 32-bit words */ + + /* + * and finally swap the first 16 bits of header in network endian + */ + *(u_int16_t*)lct_hdr = htons(*(u_int16_t*)lct_hdr); + return hlen; +bad: + return -1; + +} + /*--------------------------------------------------------*/ +int lct_hdr_add_DL(char *ptr, int hlen,u_int32_t demux_label) +{ + /* add a demux label */ + fixed_lct_hdr_t *lct_hdr = (fixed_lct_hdr_t*)ptr; + *(u_int32_t*)((char*)lct_hdr + hlen) = htonl(demux_label); + hlen += 4; + return hlen; +}/*lct_hdr_add_DL_he*/ + +/*--------------------------------------------------------*/ +int lct_hdr_add_sct_ert (char *ptr, int hlen,u_int32_t timesct,u_int32_t timeert) +{ + fixed_lct_hdr_t *lct_hdr = (fixed_lct_hdr_t*)ptr; + *(u_int32_t*)((char*)lct_hdr + hlen) = htonl(timesct); + hlen += 4; + *(u_int32_t*)((char*)lct_hdr + hlen) = htonl(timeert); + hlen += 4; + return hlen; +}/*lct_hdr_add_SCT_and_ERT*/ + + /*---------------------------------------------------------------------- + * Add a EXT_NOP header extension, using the provided lct_infos. + * Updates the lct_hdr as required. + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |L| HET=EXT_NOP | HEL = 2 | 0 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Information must be ignored by receivers | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Returns the new size of the header (bytes) with this + * header extension, or -1 if error. + * + *------------------------------------------------------------------------*/ +int lct_hdr_add_NOP_he (char *ptr , + u_int32_t hlen , + lct_infos_t *lct_infos, + u_int32_t is_last) +{ + u_int32_t word1 = 0; + word1 = (is_last << 31)|(EXT_NOP << 24)|(2 << 16); + *(u_int32_t*)(ptr + hlen) = htonl(word1); + hlen += 4; + *(u_int32_t*)(ptr + hlen) = htonl(lct_infos->NOP_info); + hlen += 4; + return hlen; +} + +/*------------------------------------------------------------------------ + * Add a TOI header extension, using the provided lct_infos. + * Updates the lct_hdr as required. + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |L| HET=EXT_TOI | HEL = 2 | 0 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | object idf | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Returns the new size of the header (bytes) with this + * header extension, or -1 if error. + * + * It must that HEL <=255 + *------------------------------------------------------------------------*/ +int lct_hdr_add_TOI_he (char *ptr , + u_int32_t hlen , + u_int32_t he_type , + u_int32_t hel , + lct_infos_t *lct_infos, + u_int32_t is_last) +{ + u_int32_t word1 = 0; + + word1 = (is_last << 31)|(EXT_TOI << 24)|(2 << 16); + *(u_int32_t*)(ptr + hlen) = htonl(word1); + hlen += 4; + *(u_int32_t*)(ptr + hlen) = htonl(lct_infos->idf_toi); + hlen += 4; + return hlen; +} +/*--------------------------------------------------------------------------*/ +/* + * Add a FPI header extension, using the provided lct_infos. + * Updates the lct_hdr as required. + * + * LCT_HDR_OPT_FOR_SPACE version (not LCT compliant): + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |L| HET=EXT_FPI | HEL = 2 |F| symbol idf | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | block idf | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * the F flag indicates that it is a FEC symbol + * + * if we do not want to use LCT_HDR_OPT_FOR_SPACE,this version suive the internet + * draft + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |L| HET=EXT_FPI | HEL = 3 |F| | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | symbol idf | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | block idf | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * Returns the new size of the header (bytes) with this + * header extension, or -1 if error. + * + */ + int +lct_hdr_add_FPI_he (char *ptr, + int hlen, + lct_infos_t *lct_infos, + u_int32_t is_last) +{ + u_int32_t word1 = 0; + word1 = (is_last << 31)|(EXT_FPI << 24) | (3 << 16) |((lct_infos->is_fec ? 1 : 0) << 15); + *(u_int32_t*)(ptr + hlen) = htonl(word1); + hlen += 4; + + *(u_int32_t*)(ptr + hlen) = htonl(lct_infos->idf_du & 0xffffffff); + hlen += 4; + + *(u_int32_t*)(ptr + hlen) = htonl(lct_infos->idf_block & 0xffffffff); + hlen += 4; + return hlen; +} +/*-----------------------------------------------------------------------*/ +/* + * Add a FTI header extension, using the provided lct_infos. + * Updates the lct_hdr as required. + * + * LCT_HDR_OPT_FOR_SPACE version (not LCT compliant): + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |L| HET=EXT_FTI | HEL = 3 | FEC encoding name | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | object length in bytes | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | block length in bytes | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Returns the new size of the header (bytes) with this + * header extension, or -1 if error. + */ + int +lct_hdr_add_FTI_he (char *ptr, + int hlen, + lct_infos_t *lct_infos, + u_int32_t is_last) +{ + u_int32_t word1 = 0; + + /* skip the FEC encoding name and use space for HET/HEL instead */ + word1 = (is_last << 31)|(EXT_FTI << 24) | (3 << 16) | + (FEC_ENCODING_NAME & 0xffff); + *(u_int32_t*)(ptr + hlen) = htonl(word1); + hlen += 4; + *(u_int32_t*)(ptr + hlen) = htonl(lct_infos->adu_len); + hlen += 4; + *(u_int32_t*)(ptr + hlen) = htonl(lct_infos->block_len); + hlen += 4; + + return hlen; +} + +/*-----------------------------------------------------------------------*/ +int lct_hdr_generat + (ALL_THE_TESTS_t choix_case, + lct_infos_t *lct_infos, + fixed_lct_hdr_t *lct_hdr) +{ + u_int32_t ertTime = 10000; + u_int32_t Past_sctTime = 10000; + int hln ; + int dl ; + int hlen ; + int cp ; + int other_ext ; + switch (choix_case) { + case TEST_NORMAL_ACCORD_DRAFT: + printf ("LCT packet according to the Internet draft:draft-ietf-rmt-bb-lct-00.txt\n"); + hln = lct_fixed_hdr_create (0,0,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + 0 , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 0 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag*/ + 0 , /*add_he_fpi_flag*/ + 0 , /*add_he_fti_flag*/ + EXT_TOI , + 2 , /*hel_he_toi */ + 2 ,/*last_he*/ + 0 , /*reverse_flag*/ + 0); /*NOP EXT*/ + break; +case TEST_NORMAL_ACCORD_MCL: +printf ("LCT packet according to MCL\n"); +hln = lct_fixed_hdr_create (0,0,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + + 0 , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 0 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag*/ + 1 , /*add_he_fpi_flag*/ + 0 , /*add_he_fti_flag*/ + EXT_TOI , + 2 , /*hel_he_toi */ + 2 ,/*last_he*/ + 0 , /*reverse_flag*/ + 0); /*NOP EXT*/ + break; + case TEST_D_NOTDL: + printf("Demux Label Present flag D = 1 and DL does not exist \n"); + hln = + lct_fixed_hdr_create (0,1,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + + 0 , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 0 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag */ + 0 , /*add_he_fpi_flag*/ + 0 , /*add_he_fti_flag*/ + EXT_TOI , + 2 ,/*hel_he_toi */ + 2 ,/*last_he*/ + 0 , /*reverse_flag*/ + 0); /*NOP EXT*/ + + break; + case TEST_V: + printf("LCT version number(V) different of 0 \n"); + /*I will do this later v = 1,2,3*/ + hln = + lct_fixed_hdr_create (1,0,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + + 0 , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 0 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag*/ + 0 , + 0 , + EXT_TOI , + 2 ,/*hel_he_toi */ + 2 ,/*last_he*/ + 0 , /*reverse_flag*/ + 0); /*NOP EXT*/ + + break; + case TEST_CP: + printf("Code point(CP) with an erroneous value\n"); + + cp = random ()/20000000; + lct_infos->codepoint = cp; + hln = + lct_fixed_hdr_create (0,0,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + + 0 , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 0 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag*/ + 0 , + 0 , + EXT_TOI , + 2 , /*hel_he_toi */ + 2 ,/*last_he*/ + 0 , /*reverse_flag*/ + 0); /*NOP EXT*/ + + break; + case TEST_L: + lct_infos->idf_toi = 1024; /*we must use header exention*/ + printf("Last header extension flag (L) = 0 in the last Header extension\n"); + hln = + lct_fixed_hdr_create (0,0,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + + 0 , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 0 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag */ + 0, + 0, + EXT_TOI , + 2 , /*hel_he_toi */ + 0 ,/*last_he*/ + 0 , /*reverse_flag*/ + 0); /*NOP EXT*/ + + break; + case TEST_NOT_EXT: + printf("EXT not listed in the draft(in the draft there are :EXT_NOP ,EXT_CCI, EST_TOI, EXT_AUTH) \n"); + other_ext = random ()/20000000; + lct_infos->idf_toi = 1024; /*we must use header exention*/ + hln = + lct_fixed_hdr_create (0,0,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + + 0 , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 0 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag*/ + 0 , + 0 , + other_ext , + 2 , /*hel_he_toi */ + 2 , /*last_he*/ + 0 , /*reverse_flag*/ + 0); /*NOP EXT*/ + + break; + case TEST_DIF_DL: + printf(" Packets of the same session with different DL\n"); + dl = random ()/20000000; + lct_infos->demux_label = dl; + hln = + lct_fixed_hdr_create (0,1,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + 0 , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 1 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag */ + 0 , + 0 , + EXT_TOI , + 2 ,/*hel_he_toi */ + 2 ,/*last_he*/ + 0 ,/*reverse_flag*/ + 0); /*NOP EXT*/ + break; + case TEST_X_NOTHE: + printf(" Header extension present flag X = 1 and Header Extensions does not exist\n"); + lct_infos->idf_toi = 1024; /*we must use header exention*/ + + hln = + lct_fixed_hdr_create (0,0,0,0,1, /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + 0 , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 0 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 0 , /*add_he_toi_flag*/ + 0 , + 0 , + EXT_TOI , + 2 , /*hel_he_toi */ + 2 ,/*last_he*/ + 0 , /*reverse_flag*/ + 0); /*NOP EXT*/ + + break; + case TEST_HDR_LEN: + printf("LCT Header length (HDR_LEN) with an erroneous value \n"); + + hlen = random ()/20000000; + hln = + lct_fixed_hdr_create (0,0,0,0,0, /*V,D,r,T,X*/ + lct_infos , + lct_hdr, + + hlen , /*hlen*/ + 0 , /*sctTime */ + 0 , /*ertTime */ + 0 , /*add_dl_flag*/ + 0 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag*/ + 0 , + 0 , + EXT_TOI , + 2 ,/*hel_he_toi */ + 2 ,/*last_he*/ + 0 ,/*reverse_flag*/ + 0); /*NOP EXT*/ + break; + /*-----------------------------------------------------------------------*/ + case TEST_HDR_PAST_SCT: + printf("Packets LCT of invalid SCT (time in the past)\n"); + + hln = + lct_fixed_hdr_create (0,0,0,1,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + 0 , /*hlen*/ + Past_sctTime ,/*sctTime */ + ertTime , /*ertTime */ + 0 , /*add_dl_flag*/ + 1 , /*add_sct_flag*/ + 1 , /*add_he_toi_flag */ + 0 , + 0 , + EXT_TOI , + 2 , /*hel_he_toi */ + 2 , /*last_he*/ + 0 , /*reverse_flag*/ + 0); /*NOP EXT*/ + break; + /*-----------------------------------------------------------------------*/ + case TEST_REVERSE_EXT: + printf("Add header extension FPI before the header extension TOI \n"); + lct_infos->idf_toi = 1024; /*we must use header exention*/ + hln = + lct_fixed_hdr_create (0,0,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + 0 , /*hlen*/ + Past_sctTime, /*sctTime */ + ertTime ,/*ertTime */ + 0 ,/*add_dl_flag*/ + 0 ,/*add_sct_flag*/ + 1 ,/*add_he_toi_flag */ + 1 , + 0 , + EXT_TOI , + 2 ,/*hel_he_toi */ + 2 ,/*last_he*/ + 1 , /*reverse_flag*/ + 0); /*NOP EXT*/ + break; + /*-----------------------------------------------------------------------*/ + case TEST_NOP_EXT: + printf("Add a EXT_NOP header extension before the header extension TOI \n"); + lct_infos->idf_toi = 1024; /*we must use header exention*/ + hln = + lct_fixed_hdr_create (0,0,0,0,0 , /*V,D,r,T,X*/ + lct_infos , + lct_hdr , + 0 , /*hlen*/ + Past_sctTime, /*sctTime */ + ertTime ,/*ertTime */ + 0 ,/*add_dl_flag*/ + 0 ,/*add_sct_flag*/ + 1 ,/*add_he_toi_flag */ + 0 , + 0 , + EXT_TOI , + 2 ,/*hel_he_toi */ + 2 ,/*last_he*/ + 0 , /*reverse_flag*/ + 1); /*NOP EXT*/ + break; + /*-----------------------------------------------------------------------*/ + default: + printf("ERROR: unknown test %d", choix_case); + exit(1); + + }/*switch*/ + +hln = hln >> 2; /*in 32 bits word*/ +return hln ; + +}/*lct_hdr_generat*/ +/* + * send a LCT packet according to the test number, Returns 0 if OK, < 0 otherwise. + */ +int main(int argc, char* argv[]) +{ + const u_char yes = 1; /* Used with SO_REUSEADDR */ + int send_s; /* Sockets for sending and receiving*/ + struct sockaddr_in mcast_group; + char IOBuf [MAXLEN]; + + lct_infos_t lct_infos_m; + fixed_lct_hdr_t *lct_hdr_m ; /* fixed size LCT header */ + int hlen ; + int choix ; + u_char ttl; + if ((argc <4)||(argc >5)) { + fprintf(stderr, "Usage: %s mcast_group port num_test [ttl]\n", argv[0]); + exit(1); + } + + memset(IOBuf, 0, sizeof(IOBuf)); + memset(&mcast_group, 0, sizeof(mcast_group)); + mcast_group.sin_family = AF_INET; + mcast_group.sin_port = htons((unsigned short int)strtol(argv[2], NULL, 0)); + mcast_group.sin_addr.s_addr = inet_addr(argv[1]); + choix =(int)strtol(argv[3], NULL, 0); + + if ( (send_s=socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror ("send socket"); + exit(1); + } + + /* If ttl supplied, set it */ + + if (argc == 5) { + ttl = (u_char)strtol(argv[4], NULL, 0); + } else { + ttl = TTL; + } + if (setsockopt(send_s, IPPROTO_IP, IP_MULTICAST_TTL, + &ttl, sizeof(ttl)) < 0) { + perror ("ttl setsockopt"); + exit(1); + } + + if (setsockopt(send_s, IPPROTO_IP, IP_MULTICAST_LOOP, + &yes, sizeof(yes)) < 0) { + perror ("loop setsockopt"); + exit(1); + } + + /*create the LCT header now*/ + lct_infos_m.payload_id_present=1; + lct_infos_m.demux_label = 1 ; + lct_infos_m.idf_toi = 1; + lct_infos_m.codepoint=0; + lct_infos_m.cci_idf=0x55001111;//CC_ID_RLC; + + + lct_infos_m.idf_block = 1; /* BLOCK identifier */ + lct_infos_m.idf_du = 1; /* DU identifier */ + lct_infos_m.is_fec = 0; /* 1 if DU has FEC content */ + + /* fields used by FTI (FEC object tx info) (previously NEWADU) */ + lct_infos_m.adu_len=300; /* Object length in bytes-unused here- */ + lct_infos_m.block_len=10; /* full-sized block length in bytes + -unused here-*/ + + + lct_infos_m.NOP_info=1024; + + lct_hdr_m = (fixed_lct_hdr_t*)IOBuf; + hlen = lct_hdr_generat (choix,(lct_infos_t *)&lct_infos_m,lct_hdr_m); + if (hlen < 0) + goto bad; + if (sendto(send_s, + IOBuf, + sizeof(IOBuf), + 0, + (struct sockaddr*)&mcast_group, + sizeof(mcast_group)) < sizeof (IOBuf)) + { + perror("sendto"); + exit(1);} + printf("\n----------------------------------------------------------------\n"); + DumpBuffer (IOBuf,sizeof(IOBuf),hlen); + printf ("The packet sent\n"); + printf("\n----------------------------------------------------------------\n"); + return 0; + bad: + return -1; + +}/*main*/ diff --git a/check/alc/test_bad_pkt.h b/check/alc/test_bad_pkt.h new file mode 100644 index 0000000..98b8ca7 --- /dev/null +++ b/check/alc/test_bad_pkt.h @@ -0,0 +1,236 @@ +/* $Id: test_bad_pkt.h,v 1.1.1.1 2003/09/03 12:45:37 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ +/* author: Zainab KHALLOUF */ + + +#if !defined(_H_TEST) +#define _H_TEST + + +#define CC_ID_RLC 0x55 /* Congestion control*/ +#define FEC_ENCODING_NAME 0 /* for Reed-Solomon (TBC) */ + +/* EH defined by LCT */ +#define EXT_NOP 0 +#define EXT_CCI 1 +#define EXT_TOI 2 +#define EXT_AUTH 3 + +/* EH defined by MCL */ +#define EXT_FPI 4 +#define EXT_FTI 5 + + +/* + * print to stdout + */ +#define PRINT_OUT(a) { \ + fprintf a; \ + fflush(stdout); \ + } + + +#ifndef min +#define min(a,b) ((a) < (b) ? (a) : (b)) +#endif + + +/* + * OS dependant code + */ + + +/* bit field order is compiler/OS dependant */ +#if defined(LINUX) || defined(WIN32) +#define _BIT_FIELDS_LTOH +#undef _BIT_FIELDS_HTOL +#elif defined(SOLARIS) +#undef _BIT_FIELDS_LTOH +#define _BIT_FIELDS_HTOL /* SunSparc is HtoL */ +#endif + + +typedef struct lct_infos { + u_int32_t payload_id_present; /* rx: block/du idf present */ + u_int32_t idf_toi; /* Obj. Id identifier */ + u_int32_t idf_block; /* BLOCK identifier */ + u_int32_t idf_du; /* DU identifier */ + u_int32_t is_fec; /* 1 if DU has FEC content */ + u_int32_t demux_label; /* demux label */ + u_int32_t codepoint; /* demux label */ + /* fields used by FTI (FEC object tx info) (previously NEWADU) */ + u_int32_t adu_len; /* ADU length in bytes */ + u_int32_t block_len; /* full-sized block length in bytes */ + /* fields used by NONEWADU */ + u_int32_t max_idf_adu; /* highest ADU identifier in session */ + /* fields used by CLOSE */ + u_int32_t close; /* CLOSE sig: boolean */ + u_int32_t cci_idf; /* opaque congestion control header */ + u_int32_t NOP_info; /*Information must ignored by the receivers*/ +} lct_infos_t; + + +typedef struct fixed_lct_hdr { +#ifdef _BIT_FIELDS_LTOH + u_int16_t toi:10, + flag_x:1, + flag_t:1, + reserved:1, + flag_d:1, + version:2; + u_int8_t hdr_len; + u_int8_t codepoint; + +#else /* the sames, in "natural" writting order... */ + u_int16_t version:2, /* LCT version Number */ + flag_d:1, /* Demux Label Present flag */ + reserved:1, /* reserved; must be zero in the sender*/ + flag_t:1, /* Transm Extension Info Present flag */ + flag_x:1, /* Header-extension fields flag */ + toi:10; /* Transport Object Identifier */ + + u_int8_t hdr_len; /* length of variable portion of LCT */ + /* header in units of 32-bit words */ + /* (starting from 3rd 32-bit word) */ + u_int8_t codepoint; /* opaque idf used by the payload decoder */ +#endif + u_int32_t cci; /* opaque congestion control header */ +} fixed_lct_hdr_t; + + +typedef enum ALL_THE_TESTS +{ + /*LCT packet according to the Internet draft:draft-ietf-rmt-bb-lct-00.txt*/ + TEST_NORMAL_ACCORD_DRAFT=0 , + /*-----------------------------------------------------------------------------------*/ + /*LCT packet according to MCL*/ + TEST_NORMAL_ACCORD_MCL=1, + /*------------------------------------------------------------------------------------*/ + /*Demux Label Present flag D = 1 and DL does not exist*/ + TEST_D_NOTDL=2, + /*-----------------------------------------------------------------------------------*/ + /*LCT version number(V) different of 0*/ + TEST_V=3 , + /*-----------------------------------------------------------------------------------*/ + /*Code point(CP) with an erroneous value*/ + TEST_CP=4 , + /*-----------------------------------------------------------------------------------*/ + /*Last header extension flag (L) = 0 in the last Header extension*/ + TEST_L=5 , + /*-----------------------------------------------------------------------------------*/ + /*EXT not listed in the draft (in the draft there are :EXT_NOP ,EXT_CCI, EST_TOI, EXT_AUTH)*/ + TEST_NOT_EXT=6, + /*-----------------------------------------------------------------------------------*/ + /* Packets of the same session with different DL*/ + TEST_DIF_DL=7 , + /*-----------------------------------------------------------------------------------*/ + /* Header extension present flag X = 1 and Header Extensions does not exist */ + TEST_X_NOTHE=8, + /*------------------------------------------------------------------------------------------*/ + /* LCT Header length (HDR_LEN) with an erroneous value*/ + TEST_HDR_LEN=9, + /*------------------------------------------------------------------------------------------*/ + /* Packets LCT of invalid SCT (time in the past) */ + TEST_HDR_PAST_SCT=10, + /*------------------------------------------------------------------------------------------*/ + /*Add Header extension FPI before the header extension TOI */ + TEST_REVERSE_EXT =11, + /*---------------------------------------------------------------------------*/ + /*Add a EXT_NOP header extension before the header extension TOI */ + TEST_NOP_EXT =12, + /*---------------------------------------------------------------------------*/ +} ALL_THE_TESTS_t; + +#undef EXTERN +#if defined(_C_TEST) +# define EXTERN +#else +# define EXTERN extern +#endif + +/*-------------------------------------------------------------------------*/ +EXTERN int lct_fixed_hdr_create (u_int16_t v , + u_int16_t d , + u_int16_t r , + u_int16_t t , + u_int16_t x , + lct_infos_t *lct_infos , + fixed_lct_hdr_t *lct_hdr , + int hlen , + u_int32_t sctTime , + u_int32_t ertTime , + int add_dl_flag , + int add_sct_ert_flag , + int add_he_toi_flag , + int add_he_fpi_flag , + int add_he_fti_flag , + int he_type , + int hel_he_toi , + int last_he_flag, + int reverse_flag, + int nop_flag); +/*-------------------------------------------------------------------------*/ + +EXTERN int lct_hdr_add_DL(char *ptr, int hlen,u_int32_t demux_label); +/*-------------------------------------------------------------------------*/ + +EXTERN int lct_hdr_add_sct_ert (char *ptr, int hlen,u_int32_t timesct,u_int32_t timeert ); +/*-------------------------------------------------------------------------*/ + +int lct_hdr_add_TOI_he (char *ptr , + u_int32_t hlen , + u_int32_t he_type , + u_int32_t hel , + lct_infos_t *lct_infos, + u_int32_t is_last); +/*-------------------------------------------------------------------------*/ + +EXTERN int lct_hdr_generat (ALL_THE_TESTS_t choix_case, lct_infos_t *lct_infos,fixed_lct_hdr_t *lct_hdr); +/*-------------------------------------------------------------------------*/ + +EXTERN void DumpBuffer (char *buf, + int len, + int to_dump); +/*-------------------------------------------------------------------------*/ +EXTERN int +lct_hdr_add_FPI_he (char *ptr, + int hlen, + lct_infos_t *lct_infos, + u_int32_t is_last); +/*--------------------------------------------------------------------------*/ +EXTERN int +lct_hdr_add_FTI_he (char *ptr, + int hlen, + lct_infos_t *lct_infos, + u_int32_t is_last); + + + + +/*--------------------------------------------------------------------------*/ +EXTERN int lct_hdr_add_NOP_he (char *ptr, + u_int32_t hlen, + lct_infos_t *lct_infos, + u_int32_t is_last); + +/*--------------------------------------------------------------------------*/ + +#endif diff --git a/check/alc/test_bad_pkt.sh b/check/alc/test_bad_pkt.sh new file mode 100755 index 0000000..eee6630 --- /dev/null +++ b/check/alc/test_bad_pkt.sh @@ -0,0 +1,28 @@ +#!/bin/sh + +# skipped ! +echo "WARNING: test skipped !!!!!!" +exit 0 + +PATH=~/work/mcl/bin/linux/ + +mclrecv2 -v1 -a230.1.2.3/2323 & +recv_pid=$! + + +for i in 0 1 2 3 4 5 6 7 8 9 10 11 12 +do + ./test_bad_pkt 230.1.2.3 2323 $i + test_pid=$! + +done + +kill -9 -s SIGKILL ${recv_pid} +wait ${recv_pid} +val=$? +if [ ${val} -ne 0 ] ; then + echo "" + echo "---------- ERROR: Test failed!----------" + echo "mclrecv2 returned ${val}\n" + exit 1 +fi diff --git a/check/alc/test_checkall.pl b/check/alc/test_checkall.pl new file mode 100755 index 0000000..ec0c5f7 --- /dev/null +++ b/check/alc/test_checkall.pl @@ -0,0 +1,11 @@ +#!/usr/bin/perl +# +# $Id: test_checkall.pl,v 1.1.1.1 2003/09/03 12:45:37 chneuman Exp $ +# +# Copyright (c) 1999-2002 Vincent ROCA - vincent.roca@inrialpes.fr +# All rights reserved. + +# check that checkall works! + +#exit 1 +exit 0 diff --git a/check/alc/test_checkall.sh b/check/alc/test_checkall.sh new file mode 100755 index 0000000..d8c8b6a --- /dev/null +++ b/check/alc/test_checkall.sh @@ -0,0 +1,27 @@ +#!/bin/sh +# +# $Id: test_checkall.sh,v 1.2 2004/12/21 14:43:44 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# check that checkall works! + +#exit 1 +exit 0 diff --git a/check/alc/test_demux_label.sh b/check/alc/test_demux_label.sh new file mode 100755 index 0000000..1146bfe --- /dev/null +++ b/check/alc/test_demux_label.sh @@ -0,0 +1,88 @@ +#!/bin/sh +# +# $Id: test_demux_label.sh,v 1.3 2004/12/21 14:43:45 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test the MCL with an application that uses different sessions +# with different demux labels. +# An object is sent on each session, containing the demux label value. + + +echo "" +echo "** TSI tests with small TSI identifiers**" +echo "" + +#./test_demux_label1_rx > /tmp/mcl_demux_rx.trc 2>&1 & +./test_demux_label1_rx & +recv_pid=$! + +sleep 1; # avoid synchro problems + +#./test_demux_label1_tx > /tmp/mcl_demux_tx.trc 2>&1 & +./test_demux_label1_tx & +send_pid=$! + +wait ${recv_pid} +recv_val=$? + +wait ${send_pid} +send_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "DEMUX_LABEL Send Failed" + exit 1 +elif [ ${recv_val} -ne 0 ] +then + echo "DEMUX_LABEL Recv Failed" + exit 1 +fi + +echo "" +echo "" +echo "** TSI tests with large TSI identifiers**" +echo "" + +#./test_demux_label2_rx > /tmp/mcl_demux_rx.trc 2>&1 & +./test_demux_label2_rx & +recv_pid=$! + +sleep 1; # avoid synchro problems + +#./test_demux_label2_tx > /tmp/mcl_demux_tx.trc 2>&1 & +./test_demux_label2_tx & +send_pid=$! + +wait ${recv_pid} +recv_val=$? + +wait ${send_pid} +send_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "DEMUX_LABEL Send Failed" + exit 1 +elif [ ${recv_val} -ne 0 ] +then + echo "DEMUX_LABEL Recv Failed" + exit 1 +fi diff --git a/check/alc/test_demux_label1_rx b/check/alc/test_demux_label1_rx new file mode 100755 index 0000000..d3cd50a Binary files /dev/null and b/check/alc/test_demux_label1_rx differ diff --git a/check/alc/test_demux_label1_rx.c b/check/alc/test_demux_label1_rx.c new file mode 100644 index 0000000..9ac505c --- /dev/null +++ b/check/alc/test_demux_label1_rx.c @@ -0,0 +1,148 @@ +/* $Id: test_demux_label1_rx.c,v 1.5 2004/08/03 06:35:56 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_demux_label1_rx.c + * for the receiver side... + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 3 /* 2 sessions max */ +#define DEMUX_LABEL_0 0 +#define DEMUX_LABEL_1 1 +#define DEMUX_LABEL_2 2 +#define BUFLEN 2400 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int dl[SESSION_NB] = /* labels to use */ + {DEMUX_LABEL_0, DEMUX_LABEL_1, DEMUX_LABEL_2}; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.1.1")); /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + int dl_rx; /* value recv'ed */ + + printf("test_demux_label1_rx: create %d receiving sessions...\n", SESSION_NB); + for (i = 0; i < BUFLEN; i++) + buf[i] = (char)i; + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("r")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + err = mcl_ctl(id[ses], MCL_OPT_DEMUX_LABEL, (void*)&dl[ses], sizeof(dl[ses])); + if (err != 0) { + printf("ERROR: mcl_ctl DEMUX_LABEL failed for session %d\n", ses); + exit(-1); + } +#if 0 + port += 20; /* incr port and addr */ + addr += 20; +#endif + } + + printf("\ntest_demux_label1_rx: finish the init of the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + if ((err = mcl_recv(id[ses], NULL, 0)) < 0) { + printf("ERROR: empty mcl_recv failed for session %d\n", ses); + exit(-1); + } + } + + printf("\ntest_demux_label1_rx: read on the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf("recv on session %d... ", ses); + if ((err = mcl_recv(id[ses], buf, BUFLEN)) < 0) { + printf("ERROR: mcl_recv failed for session %d\n", ses); + exit(-1); + } + err = sscanf(buf, "**%d**", &dl_rx); + if (err != 1) { + printf("ERROR: sscanf failed for session %d, err=%d\n", + ses, err); + exit(-1); + } + printf("found value %d in received object\n", dl_rx); + if (dl_rx != dl[ses]) { + printf("ERROR: rx bad value for session %d, expected %d\n", + ses, dl[ses]); + exit(-1); + } + } + + printf("\ntest_demux_label1_rx: close the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf("close session %d... ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_demux_label1_rx ok\n"); + return 0; +} + diff --git a/check/alc/test_demux_label1_tx b/check/alc/test_demux_label1_tx new file mode 100755 index 0000000..aa223b0 Binary files /dev/null and b/check/alc/test_demux_label1_tx differ diff --git a/check/alc/test_demux_label1_tx.c b/check/alc/test_demux_label1_tx.c new file mode 100644 index 0000000..c9bf6c3 --- /dev/null +++ b/check/alc/test_demux_label1_tx.c @@ -0,0 +1,126 @@ +/* $Id: test_demux_label1_tx.c,v 1.2 2004/02/24 16:57:32 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_demux_label1.c + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 3 /* 2 sessions max */ +#define DEMUX_LABEL_0 0 +#define DEMUX_LABEL_1 1 +#define DEMUX_LABEL_2 2 +//#define BUFLEN 2400 /* buffer size */ +#define BUFLEN 240 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int dl[SESSION_NB] = /* labels to use */ + {DEMUX_LABEL_0, DEMUX_LABEL_1, DEMUX_LABEL_2}; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.1.1")); /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + + printf("test_demux_label1_tx: create %d sending sessions...\n", SESSION_NB); + for (i = 0; i < BUFLEN; i++) + buf[i] = (char)i; + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + err = mcl_ctl(id[ses], MCL_OPT_DEMUX_LABEL, (void*)&dl[ses], sizeof(dl[ses])); + if (err != 0) { + printf("ERROR: mcl_ctl DEMUX_LABEL failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + } + printf("\ntest_demux_label1_tx: write on the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + sprintf(buf, "**%d**", dl[ses]); + if ((err = mcl_send(id[ses], buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_demux_label1_tx: close the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_demux_label1_tx ok\n"); + return 0; +} + diff --git a/check/alc/test_demux_label2_rx b/check/alc/test_demux_label2_rx new file mode 100755 index 0000000..857195b Binary files /dev/null and b/check/alc/test_demux_label2_rx differ diff --git a/check/alc/test_demux_label2_rx.c b/check/alc/test_demux_label2_rx.c new file mode 100644 index 0000000..69acfa1 --- /dev/null +++ b/check/alc/test_demux_label2_rx.c @@ -0,0 +1,150 @@ +/* $Id: test_demux_label2_rx.c,v 1.1 2004/12/21 08:45:40 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_demux_label2_rx.c + * For the receiver side... + * Same as "1" version, but with large TSI identifiers, which + * requires the use of non compact (H mode) LCT headers. + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 3 /* 2 sessions max */ +#define DEMUX_LABEL_0 0xFFFFFFF0 +#define DEMUX_LABEL_1 0xFFFFFFF1 +#define DEMUX_LABEL_2 0xFFFFFFF2 +#define BUFLEN 2400 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int dl[SESSION_NB] = /* labels to use */ + {DEMUX_LABEL_0, DEMUX_LABEL_1, DEMUX_LABEL_2}; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.1.1")); /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + int dl_rx; /* value recv'ed */ + + printf("test_demux_label1_rx: create %d receiving sessions...\n", SESSION_NB); + for (i = 0; i < BUFLEN; i++) + buf[i] = (char)i; + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("r")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + err = mcl_ctl(id[ses], MCL_OPT_DEMUX_LABEL, (void*)&dl[ses], sizeof(dl[ses])); + if (err != 0) { + printf("ERROR: mcl_ctl DEMUX_LABEL failed for session %d\n", ses); + exit(-1); + } +#if 0 + port += 20; /* incr port and addr */ + addr += 20; +#endif + } + + printf("\ntest_demux_label1_rx: finish the init of the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + if ((err = mcl_recv(id[ses], NULL, 0)) < 0) { + printf("ERROR: empty mcl_recv failed for session %d\n", ses); + exit(-1); + } + } + + printf("\ntest_demux_label1_rx: read on the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf("recv on session %d... ", ses); + if ((err = mcl_recv(id[ses], buf, BUFLEN)) < 0) { + printf("ERROR: mcl_recv failed for session %d\n", ses); + exit(-1); + } + err = sscanf(buf, "**%d**", &dl_rx); + if (err != 1) { + printf("ERROR: sscanf failed for session %d, err=%d\n", + ses, err); + exit(-1); + } + printf("found value %d in received object\n", dl_rx); + if (dl_rx != dl[ses]) { + printf("ERROR: rx bad value for session %d, expected %d\n", + ses, dl[ses]); + exit(-1); + } + } + + printf("\ntest_demux_label1_rx: close the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf("close session %d... ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_demux_label1_rx ok\n"); + return 0; +} + diff --git a/check/alc/test_demux_label2_tx b/check/alc/test_demux_label2_tx new file mode 100755 index 0000000..b3b23a8 Binary files /dev/null and b/check/alc/test_demux_label2_tx differ diff --git a/check/alc/test_demux_label2_tx.c b/check/alc/test_demux_label2_tx.c new file mode 100644 index 0000000..064e05b --- /dev/null +++ b/check/alc/test_demux_label2_tx.c @@ -0,0 +1,128 @@ +/* $Id: test_demux_label2_tx.c,v 1.1 2004/12/21 08:45:40 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_demux_label2.c + * Same as "1" version, but with large TSI identifiers, which + * requires the use of non compact (H mode) LCT headers. + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 3 /* 2 sessions max */ +#define DEMUX_LABEL_0 0xFFFFFFF0 +#define DEMUX_LABEL_1 0xFFFFFFF1 +#define DEMUX_LABEL_2 0xFFFFFFF2 +//#define BUFLEN 2400 /* buffer size */ +#define BUFLEN 240 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int dl[SESSION_NB] = /* labels to use */ + {DEMUX_LABEL_0, DEMUX_LABEL_1, DEMUX_LABEL_2}; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.1.1")); /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + + printf("test_demux_label1_tx: create %d sending sessions...\n", SESSION_NB); + for (i = 0; i < BUFLEN; i++) + buf[i] = (char)i; + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + err = mcl_ctl(id[ses], MCL_OPT_DEMUX_LABEL, (void*)&dl[ses], sizeof(dl[ses])); + if (err != 0) { + printf("ERROR: mcl_ctl DEMUX_LABEL failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + } + printf("\ntest_demux_label1_tx: write on the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + sprintf(buf, "**%d**", dl[ses]); + if ((err = mcl_send(id[ses], buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_demux_label1_tx: close the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_demux_label1_tx ok\n"); + return 0; +} + diff --git a/check/alc/test_dyn_tsi b/check/alc/test_dyn_tsi new file mode 100755 index 0000000..38874e3 Binary files /dev/null and b/check/alc/test_dyn_tsi differ diff --git a/check/alc/test_dyn_tsi.c b/check/alc/test_dyn_tsi.c new file mode 100644 index 0000000..d076529 --- /dev/null +++ b/check/alc/test_dyn_tsi.c @@ -0,0 +1,323 @@ +/* $Id: test_dyn_tsi.c,v 1.6 2004/06/15 15:37:19 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_dyn_tsi.c, both sides... + * Principle: + * The source uses TSI==1 to announce the new TSI in the first object, + * then changes to this new TSI, and sends a second object. + * The receiver starts with TSI==1, retrieves the new TSI, changes to + * this TSI dynamically, and receives the second object. + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include +#include "../../src/common/mcl_lib_api.h" + +#define DEMUX_LABEL_0 1 /* initial TSI */ +#define DEMUX_LABEL_1 99 /* new TSI */ +#define BUFLEN 2400 /* buffer size */ +#define TX_VERBOSITY 0 /* verbosity level */ +#define RX_VERBOSITY 0 /* verbosity level */ +#define NB_OBJECTS_WITH_NEW_TSI 50 +#define FEC_RATIO_STEP1 4.0 /* high ratio for step 1 */ +#define FEC_RATIO_STEP2 2.0 /* normal fec ratio for step 2 */ + + +int port = 2000; /* in host format */ +int verbose; +char object_string[] = "And this is the second object"; +int ttl = 0; /* do not leave the host */ + + +void sender (void); +void receiver (void); + + +int +main (int argc, + char *argv[]) +{ + if (argc != 2) { + printf("ERROR: bad arg count %d; \"-send\" or \"-recv\" expected\n", argc); + exit(-1); + } + if (strncmp(argv[1], "-send", strlen("-send")) == 0) { + sender(); + } else if (strncmp(argv[1], "-recv", strlen("-recv")) == 0) { + receiver(); + } else { + printf("ERROR: unknown arg %s; \"-send\" or \"-recv\" expected\n", argv[1]); + exit(-1); + } + return 0; +} + + +void +sender () +{ + int id; + int tsi[2] = {DEMUX_LABEL_0, DEMUX_LABEL_1}; /* labels to use */ + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* host format */ + int err; + char buf[BUFLEN]; + int fec_code; /* FEC codec to use (RSE for 1st part) */ + float fec_ratio; /* fec ratio to use in step 1 (high) and 2 (normal)*/ + int i; + + printf("test_dyn_tsi: SENDER, 1st step...\n"); + verbose = TX_VERBOSITY; + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed for sender\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for sender\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for sender\n"); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for sender\n"); + exit(-1); + } + } + err = mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + /* + * use RSE in this test (high FEC ratio/small block required for the + * first part of test, but other choices could be possible for the + * second part) + */ + fec_code = MCL_FEC_SCHEME_RSE_129_0; + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&fec_code, + sizeof(fec_code))) { + printf("ERROR: RSE FEC codec available but required for this test\n"); + exit(-1); + } + /* + * 1st step: send the new TSI as an object + */ + err = mcl_ctl(id, MCL_OPT_DEMUX_LABEL, (void*)&tsi[0], sizeof(tsi[0])); + if (err != 0) { + printf("ERROR: 1st mcl_ctl DEMUX_LABEL failed for sender\n"); + exit(-1); + } + + fec_ratio = FEC_RATIO_STEP1; /* high ratio for step 1 */ + err = mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio)); + if (err != 0) { + printf("ERROR: mcl_ctl MCL_OPT_FEC_RATIO failed for sender\n"); + exit(-1); + } + sprintf(buf, "**%d**", tsi[1]); + if ((err = mcl_send(id, buf, strlen(buf))) < 0) { + printf("ERROR: 1st mcl_send failed for sender\n"); + exit(-1); + } + /* + * wait a bit untill all packets have been sent before actually + * changing of TSI. Without it, there could be a risk that some + * packets of object 1 be sent with the second TSI! + */ + if ((err = mcl_wait_event(id, MCL_WAIT_EVENT_END_TX)) < 0) { + printf("ERROR: mcl_wait_event END_TX failed\n"); + exit(-1); + } + printf("test_dyn_tsi: SENDER, 2nd step...\n"); + /* + * 2nd step: change of TSI and send several objects + */ + err = mcl_ctl(id, MCL_OPT_DEMUX_LABEL, (void*)&tsi[1], sizeof(tsi[1])); + if (err != 0) { + printf("ERROR: 2nd mcl_ctl DEMUX_LABEL failed for sender\n"); + exit(-1); + } + fec_ratio = FEC_RATIO_STEP2; /* normal fec ratio for step 2 */ + err = mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio)); + if (err != 0) { + printf("ERROR: mcl_ctl MCL_OPT_FEC_RATIO failed for sender\n"); + exit(-1); + } + memset(buf, 1, BUFLEN); /* required to avoid purify UMR error reports */ + sprintf(buf, object_string); + for (i = 0; i < NB_OBJECTS_WITH_NEW_TSI; i++) { + if ((err = mcl_send(id, buf, BUFLEN)) < 0) { + printf("ERROR: 2nd mcl_send failed for sender\n"); + exit(-1); + } + } + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed for sender\n"); + exit(-1); + } + printf("test_dyn_tsi: sender ok\n"); + exit(0); +} + + +void +receiver () +{ + int id; + int tsi = DEMUX_LABEL_0; /* label to use first */ + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* host format */ + int err; + char buf[BUFLEN]; + int fec_code; /* FEC codec to use (RSE for 1st part) */ + float fec_ratio; /* fec ratio to use in step 1 (high) and 2 (normal)*/ + int i; + +#define TEST_2_STEPS /* TEST_2_STEPS should be defined */ +#ifdef TEST_2_STEPS + printf("test_dyn_tsi: RECEIVER, 1st step...\n"); +#else + printf("test_dyn_tsi: RECEIVER, test directly 2nd step...\n"); +#endif + verbose = RX_VERBOSITY; + if ((id = mcl_open("r")) < 0) { + printf("ERROR: mcl_open failed for receiver\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for receiver\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for receiver\n"); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for receiver\n"); + exit(-1); + } + } + /* + * use RSE in this test. + * specifying it here is required to specify the FEC ratio of the + * right FEC code. + */ + fec_code = MCL_FEC_SCHEME_RSE_129_0; + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&fec_code, + sizeof(fec_code))) { + printf("ERROR: RSE FEC codec available but required for this test\n"); + exit(-1); + } +#ifdef TEST_2_STEPS + /* + * 1st step: receive the new TSI (sent as an object) + */ + /* specifying the FEC ratio at a receiver is required with RSE */ + fec_ratio = FEC_RATIO_STEP1; /* high ratio for step 1 */ + err = mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio)); + if (err != 0) { + printf("ERROR: mcl_ctl MCL_OPT_FEC_RATIO failed for receiver\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_DEMUX_LABEL, (void*)&tsi, sizeof(tsi)); + if (err != 0) { + printf("ERROR: 1st mcl_ctl DEMUX_LABEL failed for receiver\n"); + exit(-1); + } + if ((err = mcl_recv(id, buf, BUFLEN)) < 0) { + printf("ERROR: 1st mcl_recv failed for receiver\n"); + exit(-1); + } + sscanf(buf, "**%d**", &tsi); + if (tsi != DEMUX_LABEL_1) { + printf("test_dyn_tsi: receiver: ERROR: bad TSI received (%d received, %d expected)\n", tsi, DEMUX_LABEL_1); + exit(-1); + } + printf("test_dyn_tsi: RECEIVER, 2nd step, change for TSI==%d...\n", tsi); +#else + tsi = 99; /* switch immediately to 2nd step */ +#endif + /* + * 2nd step: change of TSI and receive several objects + */ + /* specifying the FEC ratio at a receiver is required with RSE */ + fec_ratio = FEC_RATIO_STEP2; /* normal fec ratio for step 2 */ + err = mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio)); + if (err != 0) { + printf("ERROR: mcl_ctl MCL_OPT_FEC_RATIO failed for receiver\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_DEMUX_LABEL, (void*)&tsi, sizeof(tsi)); + if (err != 0) { + printf("ERROR: 2nd mcl_ctl DEMUX_LABEL failed for receiver\n"); + exit(-1); + } +#ifdef TEST_2_STEPS +#else + if ((err = mcl_recv(id, buf, BUFLEN)) < 0) { + printf("ERROR: 1st mcl_recv failed for receiver\n"); + exit(-1); + } +#endif + for (i = 0; i < NB_OBJECTS_WITH_NEW_TSI; i++) { + if ((err = mcl_recv(id, buf, BUFLEN)) < 0) { + printf("ERROR: 2nd mcl_recv failed for receiver\n"); + exit(-1); + } + if (strncmp(buf, object_string, strlen(object_string)) != 0) { + printf("ERROR: bad 2nd object:\n\t\"%s\" received, \"%s\" expected\n", buf, object_string); + exit(-1); + } else { + printf(" object %d rx/ok ", i); + } + } + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed for receiver\n"); + exit(-1); + } + printf("test_dyn_tsi: receiver ok\n"); + exit(0); +} + + diff --git a/check/alc/test_dyn_tsi.sh b/check/alc/test_dyn_tsi.sh new file mode 100755 index 0000000..5fede1e --- /dev/null +++ b/check/alc/test_dyn_tsi.sh @@ -0,0 +1,52 @@ +#!/bin/sh +# +# $Id: test_dyn_tsi.sh,v 1.2 2004/12/21 14:43:45 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# Principle: +# The source uses TSI==1 to announce the new TSI in the first object, +# then changes to this new TSI, and sends a second object. +# The receiver starts with TSI==1, retrieves the new TSI, changes to +# this TSI dynamically, and receives the second object. + +#./test_dyn_tsi -recv > /tmp/test_dyn_tsi_rx.trc 2>&1 & +./test_dyn_tsi -recv & +recv_pid=$! + +#./test_dyn_tsi -send > /tmp/test_dyn_tsi_tx.trc 2>&1 & +./test_dyn_tsi -send & +send_pid=$! + +wait ${recv_pid} +recv_val=$? + +wait ${send_pid} +send_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "test DYNAMIC TSI Send Failed" + exit 1 +elif [ ${recv_val} -ne 0 ] +then + echo "test DYNAMIC TSI Recv Failed" + exit 1 +fi diff --git a/check/alc/test_fcast_FLIDS.sh b/check/alc/test_fcast_FLIDS.sh new file mode 100755 index 0000000..0165eb0 --- /dev/null +++ b/check/alc/test_fcast_FLIDS.sh @@ -0,0 +1,98 @@ +#!/bin/sh +# +# $Id: test_fcast_FLIDS.sh,v 1.2 2004/12/21 14:43:45 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +# echo "WARNING: test skipped !!!!!!" +# exit 0 + +# +# fcast test sending a single file with FLIDS congestion control mode, without giving any path +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux SINGLE FILE Send/Recv Test" + fcast_path="../../bin/linux/fcast" + ;; + + SunOS) + echo "Running FCAST Solaris SINGLE FILE Send/Recv Test" + fcast_path="../../bin/solaris/fcast" + ;; + + FreeBSD) + echo "Running FCAST Solaris SINGLE FILE Send/Recv Test" + fcast_path="../../bin/freebsd/fcast" + ;; + # other OS???? todo +esac + +# +# multicast tests only +# + +# for debug... +#verbosity_recv='-v1' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +echo "${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -cc2 -p1024" +echo "${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -cc2 -p1024/1000000 -fec1.5 i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -cc2 -p1024 & +fcast_recv_pid=$! + +cd ../send/Other_Files +../../../${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -cc2 -p1024/100000 -fec1.5 i-am-a-BIG.file & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +else + exit 0 +fi diff --git a/check/alc/test_fcast_NO_CC.sh b/check/alc/test_fcast_NO_CC.sh new file mode 100755 index 0000000..fffcf27 --- /dev/null +++ b/check/alc/test_fcast_NO_CC.sh @@ -0,0 +1,98 @@ +#!/bin/sh +# +# $Id: test_fcast_NO_CC.sh,v 1.2 2004/12/21 14:43:45 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +# echo "WARNING: test skipped !!!!!!" +# exit 0 + +# +# fcast test sending a single file without congestion control mode, without giving any path +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux SINGLE FILE Send/Recv Test" + fcast_path="../../bin/linux/fcast" + ;; + + SunOS) + echo "Running FCAST Solaris SINGLE FILE Send/Recv Test" + fcast_path="../../bin/solaris/fcast" + ;; + + FreeBSD) + echo "Running FCAST Solaris SINGLE FILE Send/Recv Test" + fcast_path="../../bin/freebsd/fcast" + ;; + # other OS???? todo +esac + +# +# multicast tests only +# + +# for debug... +#verbosity_recv='-v1' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +echo "${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -cc0 -p1024" +echo "${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -cc0 -p1024/1000000 -fec1.5 i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -cc1 -p1024 & +fcast_recv_pid=$! + +cd ../send/Other_Files +../../../${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -cc1 -p1024/100000 -fec1.5 i-am-a-BIG.file & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +else + exit 0 +fi diff --git a/check/alc/test_fcast_RLC.sh b/check/alc/test_fcast_RLC.sh new file mode 100755 index 0000000..f576133 --- /dev/null +++ b/check/alc/test_fcast_RLC.sh @@ -0,0 +1,98 @@ +#!/bin/sh +# +# $Id: test_fcast_RLC.sh,v 1.2 2004/12/21 14:43:46 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +# echo "WARNING: test skipped !!!!!!" +# exit 0 + +# +# fcast test sending a single file with RLC congestion control mode, without giving any path +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux SINGLE FILE Send/Recv Test" + fcast_path="../../bin/linux/fcast" + ;; + + SunOS) + echo "Running FCAST Solaris SINGLE FILE Send/Recv Test" + fcast_path="../../bin/solaris/fcast" + ;; + + FreeBSD) + echo "Running FCAST Solaris SINGLE FILE Send/Recv Test" + fcast_path="../../bin/freebsd/fcast" + ;; + # other OS???? todo +esac + +# +# multicast tests only +# + +# for debug... +#verbosity_recv='-v1' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +echo "${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -cc1 -p1024" +echo "${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -cc1 -p1024/1000000 -fec1.5 i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -cc1 -p1024 & +fcast_recv_pid=$! + +cd ../send/Other_Files +../../../${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -cc1 -p1024/100000 -fec1.5 i-am-a-BIG.file & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +else + exit 0 +fi diff --git a/check/alc/test_fcast_mcl_modes.sh b/check/alc/test_fcast_mcl_modes.sh new file mode 100755 index 0000000..689e938 --- /dev/null +++ b/check/alc/test_fcast_mcl_modes.sh @@ -0,0 +1,197 @@ +#!/bin/sh +# +# $Id: test_fcast_mcl_modes.sh,v 1.4 2005/03/23 14:05:00 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# +# fcast validation script #3 : Fcast options and MCL Modes Tests +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux Send/Recv Test #3" + fcast_path="../../bin/linux/fcast" + ;; + + SunOS) + echo "Running FCAST Solaris Send/Recv Test #3" + fcast_path="../../bin/solaris/fcast" + ;; + + FreeBSD) + echo "Running FCAST Solaris Send/Recv Test #3" + fcast_path="../../bin/freebsd/fcast" + ;; + # other OS???? todo +esac + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='' +#verbosity_send='-v1' # sender part +verbosity_send='' + +# file sent +file='./Other_Files/i-am-a-BIG.file' + + +echo "" +echo "** Multicast tests only..." +echo "" + +echo "--- Speed Optmimization Test..." +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -force -phigh -ospeed -a225.1.2.3/9991 & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -phigh -ospeed -a225.1.2.3/9991 ${file} & +fcast_send_pid=$! + + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + + +cd ../.. +diff ./fcast_test/send/${file} ./fcast_test/recv/${file} +diff_val=$? + +if [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + echo "-- Test OK!" +fi + + +echo "--- Space Optmimization Test..." +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -force -phigh -ospace -a225.2.3.4/9992 & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -phigh -ospace -a225.2.3.4/9992 ${file} & +fcast_send_pid=$! + + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? + +cd ../.. +diff ./fcast_test/send/${file} ./fcast_test/recv/${file} +diff_val=$? + +if [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + echo "-- Test OK!" +fi + +echo "--- CPU Optmimization Test..." +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -force -phigh -ocpu -a225.3.4.5/9993 & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -phigh -ocpu -a225.3.4.5/9993 ${file} & +fcast_send_pid=$! + + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + + +cd ../.. +diff ./fcast_test/send/${file} ./fcast_test/recv/${file} +diff_val=$? + + +if [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + echo "-- Test OK!" + exit 0 +fi + diff --git a/check/alc/test_fcast_non_recursive.sh b/check/alc/test_fcast_non_recursive.sh new file mode 100755 index 0000000..9302641 --- /dev/null +++ b/check/alc/test_fcast_non_recursive.sh @@ -0,0 +1,157 @@ +#!/bin/sh +# +# $Id: test_fcast_non_recursive.sh,v 1.3 2004/12/21 14:43:46 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# +# fcast validation script #2 : non recursive Send/Recv Test +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux non recursive send/recv test" + fcast_path="../../bin/linux/fcast" + ;; + + SunOS) + echo "Running FCAST Solaris non recursive send/recv test" + fcast_path="../../bin/solaris/fcast" + ;; + + FreeBSD) + echo "Running FCAST Solaris non recursive send/recv test" + fcast_path="../../bin/freebsd/fcast" + ;; + + + # other OS???? todo +esac + +# for debug... +#verbosity_recv='-v1' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +# file sent +file='./Other_Files/i-am-a-BIG.file' + + +# +# multicast tests first +# +echo "" +echo "** Multicast tests..." +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -never -phigh -a225.3.4.5/9998 & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -phigh -a225.3.4.5/9998 ${file} & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +diff ./fcast_test/send/${file} ./fcast_test/recv/${file} +diff_val=$? + + +if [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + +# +# and unicast tests... +# +echo "" +echo "** And unicast tests now..." +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -never -a127.0.0.1/9998 & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -a127.0.0.1/9998 ${file} & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +diff ./fcast_test/send/${file} ./fcast_test/recv/${file} +diff_val=$? + + +# do not test send_val return value here as in unicast, +# the sender is always stopped as soon as the receiver leaves +# with a sendmsg error. This is normal so ignore it and only +# rely on diff tests +# +if [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + exit 0 +fi diff --git a/check/alc/test_fcast_objaggr_mode.sh b/check/alc/test_fcast_objaggr_mode.sh new file mode 100755 index 0000000..3f582d0 --- /dev/null +++ b/check/alc/test_fcast_objaggr_mode.sh @@ -0,0 +1,101 @@ +#!/bin/sh +# +# $Id: test_fcast_objaggr_mode.sh,v 1.3 2004/12/21 14:43:46 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# +# fcast validation script #3 : Fcast options and MCL Modes Tests +# +# +host_name=`uname -s` + + +echo "Running FCAST object aggregation test" +case ${host_name} in +Linux) + fcast_path="../../bin/linux/fcast" + ;; + +SunOS) + fcast_path="../../bin/solaris/fcast" + ;; + +FreeBSD) + fcast_path="../../bin/freebsd/fcast" + ;; +# other OS???? todo +esac + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='' +#verbosity_send='-v1' # sender part +verbosity_send='' + +echo "" +echo "${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -phigh " +echo "${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -phigh -objaggr -R ./" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -phigh & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -phigh -objaggr -R ./ & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +diff ./fcast_test/send/${file} ./fcast_test/recv/${file} +diff_val=$? + + +if [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + echo "-- Test OK!" + exit 0 +fi + diff --git a/check/alc/test_fcast_simple_file.sh b/check/alc/test_fcast_simple_file.sh new file mode 100755 index 0000000..c068853 --- /dev/null +++ b/check/alc/test_fcast_simple_file.sh @@ -0,0 +1,98 @@ +#!/bin/sh +# +# $Id: test_fcast_simple_file.sh,v 1.3 2004/12/21 14:43:47 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +# echo "WARNING: test skipped !!!!!!" +# exit 0 + +# +# fcast test sending a single file without giving any path +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux SINGLE FILE Send/Recv Test" + fcast_path="../../bin/linux/fcast" + ;; + + SunOS) + echo "Running FCAST Solaris SINGLE FILE Send/Recv Test" + fcast_path="../../bin/solaris/fcast" + ;; + + FreeBSD) + echo "Running FCAST Solaris SINGLE FILE Send/Recv Test" + fcast_path="../../bin/freebsd/fcast" + ;; + # other OS???? todo +esac + +# +# multicast tests only +# + +# for debug... +#verbosity_recv='-v1' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +echo "${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -phigh" +echo "${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -phigh i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -phigh & +fcast_recv_pid=$! + +cd ../send/Other_Files +../../../${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -phigh i-am-a-BIG.file & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +else + exit 0 +fi diff --git a/check/alc/test_fcast_xfert.sh b/check/alc/test_fcast_xfert.sh new file mode 100755 index 0000000..88879b0 --- /dev/null +++ b/check/alc/test_fcast_xfert.sh @@ -0,0 +1,169 @@ +#!/bin/sh +# +# $Id: test_fcast_xfert.sh,v 1.4 2004/12/21 14:43:47 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +# echo "WARNING: test skipped !!!!!!" +# exit 0 + +# +# fcast validation script #1 : Send/Recv Test +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux Send/Recv Test" + fcast_path="../../bin/linux/fcast" + ;; + + SunOS) + echo "Running FCAST Solaris Send/Recv Test" + fcast_path="../../bin/solaris/fcast" + ;; + + FreeBSD) + echo "Running FCAST Solaris Send/Recv Test" + fcast_path="../../bin/freebsd/fcast" + ;; + # other OS???? todo +esac + +# +# multicast tests first +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +echo "" +echo "** Multicast tests..." +echo "" +echo "${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -phigh" +echo "${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -phigh -R ./" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never -ospeed -phigh & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -ospeed -phigh -R ./ & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +diff -r ./fcast_test/send ./fcast_test/recv +diff_val=$? + + +if [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + +# +# and now unicast tests... +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +echo "" +echo "** And unicast tests now..." +echo "" +echo "${fcast_path} ${verbosity_recv} -recv -a127.0.0.1/9998 -never" +echo "${fcast_path} ${verbosity_send} -send -a127.0.0.1/9998 -R ./" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -a127.0.0.1/9998 -never & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -a127.0.0.1/9998 -R ./ & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +diff -r ./fcast_test/send ./fcast_test/recv +diff_val=$? + + +# do not test send_val return value here as in unicast, +# the sender is always stopped as soon as the receiver leaves +# with a sendmsg error. This is normal so ignore it and only +# rely on diff tests +# +if [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + exit 0 +fi diff --git a/check/alc/test_flute_xfert.sh b/check/alc/test_flute_xfert.sh new file mode 100755 index 0000000..04a5568 --- /dev/null +++ b/check/alc/test_flute_xfert.sh @@ -0,0 +1,174 @@ +#!/bin/sh +# +# $Id: test_flute_xfert.sh,v 1.10 2005/02/23 17:32:35 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + +# +# flute validation script #1 : Send/Recv Test +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# multicast tests first +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** Multicast tests..." +echo "" +echo "${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -phigh" +echo "${flute_path} ${verbosity_send} -send -a225.1.2.3/9991 -phigh ./Other_Files/i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -phigh & +flute_recv_pid=$! + +cd ../send +../../${flute_path} ${verbosity_send} -send -a225.1.2.3/9991 -phigh ./Other_Files/i-am-a-BIG.file & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../.. +#diff -r ./fcast_test/send ./fcast_test/recv +diff ./fcast_test/send/Other_Files/i-am-a-BIG.file ./fcast_test/recv/Other_Files/i-am-a-BIG.file + +diff_val=$? + + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + +# +# and now unicast tests... +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** And unicast tests now..." +echo "" +echo "${flute_path} ${verbosity_recv} -recv -a127.0.0.1/9998 -phigh" +echo "${flute_path} ${verbosity_send} -send -a127.0.0.1/9998 -phigh ./Other_Files/i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${flute_path} ${verbosity_recv} -recv -a127.0.0.1/9998 -phigh & +flute_recv_pid=$! + +cd ../send +../../${flute_path} ${verbosity_send} -send -a127.0.0.1/9998 -phigh ./Other_Files/i-am-a-BIG.file & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +#diff -r ./fcast_test/send ./fcast_test/recv +diff ./fcast_test/send/Other_Files/i-am-a-BIG.file ./fcast_test/recv/Other_Files/i-am-a-BIG.file + +diff_val=$? + + +# do not test send_val return value here as in unicast, +# the sender is always stopped as soon as the receiver leaves +# with a sendmsg error. This is normal so ignore it and only +# rely on diff tests +# +if [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + exit 0 +fi diff --git a/check/alc/test_multi_sessions.sh b/check/alc/test_multi_sessions.sh new file mode 100755 index 0000000..7dc7e36 --- /dev/null +++ b/check/alc/test_multi_sessions.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +# $Id: test_multi_sessions.sh,v 1.2 2004/12/21 14:43:47 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test the MCL with a multi-session application + +#./test_multi_sessions1 & +#pid=$! +#wait ${pid} +#val=$? + +./test_multi_sessions1 +val=$? + +echo "returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +fi + +./test_multi_sessions2 +val=$? + +echo "returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +fi + +exit 0 diff --git a/check/alc/test_multi_sessions1 b/check/alc/test_multi_sessions1 new file mode 100755 index 0000000..c981162 Binary files /dev/null and b/check/alc/test_multi_sessions1 differ diff --git a/check/alc/test_multi_sessions1.c b/check/alc/test_multi_sessions1.c new file mode 100644 index 0000000..c49758b --- /dev/null +++ b/check/alc/test_multi_sessions1.c @@ -0,0 +1,120 @@ +/* $Id: test_multi_sessions1.c,v 1.3 2004/05/12 12:43:28 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_multi_sessions1.c + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#ifdef SOLARIS /* with solaris the max # of opened fd is much lower! */ +#define SESSION_NB 5 /* number of sessions */ +#else +#define SESSION_NB 10 /* number of sessions */ +#endif +#define BUFLEN 2400 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("230.0.0.0")); /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + + printf("test_multi_sessions1: create %d sending sessions...\n", SESSION_NB); + for (i = 0; i < BUFLEN; i++) + buf[i] = (char)i; + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + err = mcl_ctl(id[ses], MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + port += 10; /* incr port and addr */ + addr += 10; + } + printf("\ntest_multi_sessions1: write on the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_send(id[ses], buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_multi_sessions1: close the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_multi_sesions1 ok\n"); + return 0; +} + diff --git a/check/alc/test_multi_sessions2 b/check/alc/test_multi_sessions2 new file mode 100755 index 0000000..c71c200 Binary files /dev/null and b/check/alc/test_multi_sessions2 differ diff --git a/check/alc/test_multi_sessions2.c b/check/alc/test_multi_sessions2.c new file mode 100644 index 0000000..37548c5 --- /dev/null +++ b/check/alc/test_multi_sessions2.c @@ -0,0 +1,119 @@ +/* $Id: test_multi_sessions2.c,v 1.3 2004/05/12 12:43:28 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_multi_sessions2.c + * for the receiver side, no read... + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#ifdef SOLARIS /* with solaris the max # of opened fd is much lower! */ +#define SESSION_NB 5 /* number of sessions */ +#else +#define SESSION_NB 10 /* number of sessions */ +#endif + +#define VERBOSITY 0 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("230.0.0.0")); /* in host format! */ + int err; + int ses; + int verbose = VERBOSITY; + + printf("test_multi_sessions2: create %d receiving sessions...\n", SESSION_NB); + + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("r")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + err = mcl_ctl(id[ses], MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + port += 20; /* incr port and addr */ + addr += 20; + } + printf("\ntest_multi_sessions2: finish init of the %d sessions with null recv...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_recv(id[ses], NULL, 0)) < 0) { + printf("ERROR: mcl_recv failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_multi_sessions2: close the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_multi_sesions2 ok\n"); + return 0; +} + diff --git a/check/alc/test_no_tx b/check/alc/test_no_tx new file mode 100755 index 0000000..18b226f Binary files /dev/null and b/check/alc/test_no_tx differ diff --git a/check/alc/test_no_tx.c b/check/alc/test_no_tx.c new file mode 100644 index 0000000..6703c15 --- /dev/null +++ b/check/alc/test_no_tx.c @@ -0,0 +1,119 @@ +/* $Id: test_no_tx.c,v 1.2 2004/02/24 16:57:42 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_no_tx.c + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#include /* for sleep */ +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id = 0; + int port = 2324; + unsigned long addr = ntohl(inet_addr("230.1.2.3")); + int err; + + printf("test_no_tx: open(r)/close\n"); + if ((id = mcl_open("r")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } + if (port > 0) { /* in host format! */ + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed\n"); + exit(-1); + } + } + if (addr > 0) { /* in host format! */ + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed\n"); + exit(-1); + } + } + err = mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed\n"); + exit(-1); + } + printf("... ok\n"); + + printf("test_no_tx: open(w)/close\n"); + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } + if (port > 0) { /* in host format! */ + mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed\n"); + exit(-1); + } + } + if (addr > 0) { /* in host format! */ + mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed\n"); + exit(-1); + } + } + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed\n"); + exit(-1); + } + printf("... ok\n"); + +#ifdef WIN32 + _sleep(1000); /* for the wait pid in test_no_tx.sh to work properly */ +#else + sleep(1); /* for the wait pid in test_no_tx.sh to work properly */ +#endif + + return(0); +} + diff --git a/check/alc/test_no_tx.sh b/check/alc/test_no_tx.sh new file mode 100755 index 0000000..cb9da57 --- /dev/null +++ b/check/alc/test_no_tx.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# +# $Id: test_no_tx.sh,v 1.2 2004/12/21 14:43:48 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test the MCL with an application that only performs +# mcl_open and immediately mcl_close + +./test_no_tx +val=$? + +echo "${pid} returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +else + exit 0 +fi + diff --git a/check/alc/test_rebootable_client b/check/alc/test_rebootable_client new file mode 100755 index 0000000..9137adf Binary files /dev/null and b/check/alc/test_rebootable_client differ diff --git a/check/alc/test_rebootable_client.c b/check/alc/test_rebootable_client.c new file mode 100644 index 0000000..e266ca6 --- /dev/null +++ b/check/alc/test_rebootable_client.c @@ -0,0 +1,219 @@ +/* $Id: test_rebootable_client.c,v 1.4 2004/11/29 17:07:26 chneuman Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_rebootable_client.c + * Test MCL robustness in front of either client or server reboot. + * A server reboot triggers a TSI update, in order to distinguish + * the sessions before and after the reboot. + * A client reboot must not affect reception. + * The session follows an on-demand delivery mode in order to + * enable asynchronous client arrivals. + * Two MCL sessions are created: a control session (TSI=0) used by + * the server to announce communicate the new TSI to use, and a + * data session (using the new TSI) to convey data. + */ + +#include +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +/* + * print and exit + */ +#define EXIT(a) { printf a; fflush(stdout); exit(-1); } + +/* + * test, print and exit if error (i.e. if != 0) + */ +#define EXIT_ON_ERROR(err, a) { if (err) { EXIT(a) } } + + +#define BUFLEN 150 /* buffer size */ +#define VERBOSITY_CTRL 0 /* verbosity level for control session*/ +#define VERBOSITY_DATA 0 /* verbosity level for data session */ +#define SESSION_NB 2 /* two sessions: ctrl (0), data (1) */ +#define CTRL_IDX 0 /* index in tabs for ctrl session */ +#define DATA_IDX 1 /* index in tabs for data session */ + +int id[SESSION_NB]; /* MCL session identifiers */ +int port[SESSION_NB]; +unsigned long addr[SESSION_NB]; +int verbose[SESSION_NB]; +int cur_TSI = 0; /* current Transport Session Id to */ + /* use for data session */ + + +/* + * Create and setup a session (ctrl or data) + */ +void +setup_session (int index) +{ + int err; /* error return value */ + + if ((id[index] = mcl_open("r")) < 0) + EXIT(("client/setup_session: ERROR: mcl_open failed for session %d\n", index)) + if (verbose[index] > 0) { + err = mcl_ctl(id[index], MCL_OPT_VERBOSITY, (void*)&verbose[index], + sizeof(verbose[index])); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR: mcl_ctl VERBOSITY failed for session %d\n", index)) + } + /* Select the appropriate multicast address and port */ + err = mcl_ctl(id[index], MCL_OPT_ADDR, (void*)&addr[index], sizeof(addr[index])); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR, MCL_OPT_ADDR failed for session %d\n", index)) + err = mcl_ctl(id[index], MCL_OPT_PORT, (void*)&port[index], sizeof(port[index])); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR, MCL_OPT_PORT failed for session %d\n", index)) + if (index == CTRL_IDX) { + int set = 1; + /* switch to immediate delivery mode */ + err = mcl_ctl(id[index], MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, (void*)&set, sizeof(set)); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR, MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI failed\n")) + } +} + + +/* + * MCL control session management. + * Receives new TSI announcements, and controls the data session + * accordingly. + */ +void +ctrl_mgmt (void) +{ + int new_TSI = 0; /* Transport Session Id just received. It can */ + /* be a reminder, or a new TSI... */ + int ret; + int err; /* error return value */ + fd_set readfs; + + FD_ZERO(&readfs); + FD_SET(id[CTRL_IDX], &readfs); + /* don't wait here */ + ret = mcl_select(id[CTRL_IDX]+1, &readfs, NULL, NULL, NULL); + if (ret < 0) + EXIT(("client/ctrl_mgmt: ERROR, mcl_select failed")) + if (ret == 0) { + /* nothing received, so return */ + /*printf("client/ctrl_mgmt: no new TSI received yet\n");*/ + return; + } + /* something available... */ + if (ret != 1) + EXIT(("client/ctrl_mgmt: ERROR, expected ret == 1, got %d", ret)) + if ((ret = mcl_recv(id[CTRL_IDX], &new_TSI, sizeof(new_TSI))) < 0) + EXIT(("client/ctrl_mgmt: ERROR, control session closed")) + if (ret == 0) + EXIT(("client/ctrl_mgmt: ERROR, read on control session returns 0 whereas mcl_select() says there's data!")) + new_TSI = ntohl(new_TSI); + if (new_TSI == cur_TSI) { + /* nothing to do... this is just a reminder */ + printf("test_rebootable_client: recvd a reminder for TSI=%d\n", new_TSI); + return; + } + /* + * switch to new TSI. + * It requires to close the close the current data + * session (to flush buffers), reopen a new session + * and specifying the new TSI to use. + */ + printf("test_rebootable_client: switch to new TSI=%d...\n", new_TSI); + mcl_close(id[DATA_IDX]); + setup_session(DATA_IDX); + err = mcl_ctl(id[DATA_IDX], MCL_OPT_DEMUX_LABEL, (void*)&new_TSI, sizeof(new_TSI)); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR, MCL_OPT_DEMUX_LABEL failed for data session\n")) +} + + +int +main (int argc, + char *argv[]) +{ + char buf[BUFLEN]; + struct timeval timeout; + int ret; + fd_set readfs; + + port[CTRL_IDX] = 2000; /* in host format (required by MCL) */ + port[DATA_IDX] = 2100; + addr[CTRL_IDX] = ntohl(inet_addr("225.1.0.0")); /* in host format */ + /* (required by MCL) */ + addr[DATA_IDX] = ntohl(inet_addr("225.2.0.0")); + verbose[CTRL_IDX] = VERBOSITY_CTRL; + verbose[DATA_IDX] = VERBOSITY_DATA; + + printf("test_rebootable_client: create and init two sessions...\n"); + setup_session(CTRL_IDX); + setup_session(DATA_IDX); + + /* + * start data reception now. + */ + while (1) { + FD_ZERO(&readfs); + FD_SET(id[DATA_IDX], &readfs); + timeout.tv_sec = 0; /* 0.1 second timeout */ + timeout.tv_usec = 100000; + ret = mcl_select(id[DATA_IDX]+1, &readfs, NULL, NULL, &timeout); + if (ret < 0) { + EXIT(("client/main: ERROR, mcl_select failed")) + } else if (ret == 0) { + /* nothing received, check the control session now... */ + /*printf("client/ctrl_mgmt: no new data received yet\n");*/ + ctrl_mgmt(); + } else if (ret != 1) { + EXIT(("client/main: ERROR, expected ret == 1, got %d", ret)) + } else { + if ((ret = mcl_recv(id[DATA_IDX], buf, BUFLEN)) < 0) + EXIT(("client/main: data session closed\n")) +#if 0 + if (ret != BUFLEN) + EXIT(("client/main: ERROR, bad len (received %d, expected %d)\n", ret, BUFLEN)) +#endif + printf("received:\t\t%s\n", buf); +#if 0 + printf("\n\t... test_rebootable_client ok\n"); + return 0; +#endif + } + } + return -1; +} + diff --git a/check/alc/test_rebootable_server b/check/alc/test_rebootable_server new file mode 100755 index 0000000..a9013eb Binary files /dev/null and b/check/alc/test_rebootable_server differ diff --git a/check/alc/test_rebootable_server.c b/check/alc/test_rebootable_server.c new file mode 100644 index 0000000..b4486d1 --- /dev/null +++ b/check/alc/test_rebootable_server.c @@ -0,0 +1,242 @@ +/* $Id: test_rebootable_server.c,v 1.2 2004/11/29 17:07:26 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_rebootable_server.c + * Test MCL robustness in front of either client or server reboot. + * A server reboot triggers a TSI update, in order to distinguish + * the sessions before and after the reboot. + * A client reboot must not affect reception. + * The session follows an on-demand delivery mode in order to + * enable asynchronous client arrivals. + * Two MCL sessions are created: a control session (TSI=0) used by + * the server to announce communicate the new TSI to use, and a + * data session (using the new TSI) to convey data. + */ + +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include /* for sleep */ +#include "../../src/common/mcl_lib_api.h" + +/* + * print and exit + */ +#define EXIT(a) { printf a; fflush(stdout); exit(-1); } + +/* + * test, print and exit if error (i.e. if != 0) + */ +#define EXIT_ON_ERROR(err, a) { if (err) { EXIT(a) } } + + +#define BUFLEN 150 /* buffer size */ +#define VERBOSITY_CTRL 0 /* verbosity level for control session*/ +#define VERBOSITY_DATA 0 /* verbosity level for data session */ +#define SESSION_NB 2 /* two sessions: ctrl (0), data (1) */ +#define CTRL_IDX 0 /* index in tabs for ctrl session */ +#define DATA_IDX 1 /* index in tabs for data session */ + +int id[SESSION_NB]; /* MCL session identifiers */ +int port[SESSION_NB]; +unsigned long addr[SESSION_NB]; +int verbose[SESSION_NB]; +int cur_TSI = -1; /* current Transport Session Id to */ + /* use for data session */ +int cur_TOI = -1; /* current Transport Object Id to */ + /* use to carry the TSI announcement */ + + +/* + * Create and setup a session (ctrl or data) + */ +void +setup_session (int index) +{ + int err; /* error return value */ + int delivery_mode = DEL_MODE_ON_DEMAND; + + if ((id[index] = mcl_open("w")) < 0) + EXIT(("server/setup_session: ERROR: mcl_open failed for session %d\n", index)) + if (verbose[index] > 0) { + err = mcl_ctl(id[index], MCL_OPT_VERBOSITY, (void*)&verbose[index], + sizeof(verbose[index])); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR: mcl_ctl VERBOSITY failed for session %d\n", index)) + } + /* Select the appropriate multicast address and port */ + err = mcl_ctl(id[index], MCL_OPT_ADDR, (void*)&addr[index], sizeof(addr[index])); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR, MCL_OPT_ADDR failed for session %d\n", index)) + err = mcl_ctl(id[index], MCL_OPT_PORT, (void*)&port[index], sizeof(port[index])); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR, MCL_OPT_PORT failed for session %d\n", index)) + /* Switch to "on demand" delivery mode */ + err = mcl_ctl(id[index], MCL_OPT_DELIVERY_MODE, (void*)&delivery_mode, + sizeof(delivery_mode)); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR, MCL_OPT_DELIVERY_MODE failed\n")) + if (index == CTRL_IDX) { + float fec = 1.0; /* n/k = 1.0 means no FEC */ + /* no need for FEC here */ + err = mcl_ctl(id[index], MCL_OPT_FEC_RATIO, (void*)&fec, sizeof(fec)); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR, MCL_OPT_FEC_RATIO failed\n")) + + } +} + + +/* + * MCL control session management. + * Retrieves the new TSI to use for the data session (i.e. TSI of the + * previous data session + 1) + * and the new TOI to use for the control session (i.e. TSI of the + * previous control session + 1) + * which are both stored on a permanent location (i.e. a file), then + * send the TSI periodically in the control session (in case a client + * is restarted) in the object of identifier TOI. + */ +void +ctrl_mgmt (void) +{ + int buf[1]; /* buffer sent on ctrl session which */ + /* contains TSI in network format */ + char tsi_file_name[] = "./test_rebootable_server_tsi_repository.txt"; + /* name of permanent TSI depository */ + int fd_tsi = -1; /* fd to file containing the TSI value*/ + FILE *FILE_tsi = NULL; /* ptr to file containing TSI value */ + int ret; + int err; /* error return value */ + + /* + * First, retrieve the TSI to use. If the variable cur_TSI is not set, + * (e.g. after a reboot), then retrieve it from disk file, if any, + * or create this file. + */ + if (cur_TSI == -1) { + /* server has been restarted, so search the TSI from disk */ + if ((fd_tsi = open(tsi_file_name, O_RDWR)) < 0) { + if (errno != ENOENT) { + perror("server/ctrl_mgmt: open failed 1"); + EXIT(("server/ctrl_mgmt: ERROR while opening file %s\n", tsi_file_name)) + } + /* does not exist */ + printf("\t\ttest_rebootable_server: first time started, use TSI=0\n"); + cur_TSI = 1; /* reset TSI (must be >= 0) */ + cur_TOI = 1; /* reset TSI (must be >= 1) */ + if ((fd_tsi = open(tsi_file_name, O_WRONLY|O_CREAT, S_IRWXU)) < 0) { + perror("server/ctrl_mgmt: open failed 2"); + EXIT(("server/ctrl_mgmt: ERROR while creating file %s\n", tsi_file_name)) + } + if ((FILE_tsi = fdopen(fd_tsi, "w")) == NULL) { + perror("server/ctrl_mgmt: fdopen failed"); + EXIT(("server/ctrl_mgmt: ERROR, fdopen failed\n")) + } + } else { + /* read the value, increment it, and save it */ + if ((FILE_tsi = fdopen(fd_tsi, "r+")) == NULL) { + perror("server/ctrl_mgmt: fdopen failed"); + EXIT(("server/ctrl_mgmt: ERROR, fdopen failed\n")) + } + if ((ret = fscanf(FILE_tsi, "%d %d", &cur_TSI, &cur_TOI)) != 2) { + perror("server/ctrl_mgmt: fscanf failed"); + EXIT(("server/ctrl_mgmt: ERROR, fscanf failed\n")) + } + rewind(FILE_tsi); + printf("\ttest_rebootable_server: restarted, use TSI=%d, TOI=%d\n", cur_TSI, cur_TOI); + } + /* store the next TSI and TOI to use, flush it and close */ + fprintf(FILE_tsi, "%d %d", cur_TSI+1, cur_TOI+1); + fflush(FILE_tsi); + if (fclose(FILE_tsi) != 0) { + perror("server/ctrl_mgmt: fclose failed"); + EXIT(("server/ctrl_mgmt: ERROR, fclose failed\n")) + } + /* fclose() implicitely issues a close() too */ + /* set the new TSI on the data session */ + printf("\ttest_rebootable_server: switch to new TSI=%d\n", cur_TSI); + err = mcl_ctl(id[DATA_IDX], MCL_OPT_DEMUX_LABEL, (void*)&cur_TSI, sizeof(cur_TSI)); + EXIT_ON_ERROR(err, ( + "server/ctrl_mgmt: ERROR, MCL_OPT_DEMUX_LABEL failed for data session\n")) + /* set the new TOI for the control session */ + printf("\ttest_rebootable_server: switch to new TOI=%d\n", cur_TOI); + err = mcl_ctl(id[CTRL_IDX], MCL_OPT_SET_NEXT_TOI, (void*)&cur_TOI, sizeof(cur_TOI)); + EXIT_ON_ERROR(err, ( + "server/ctrl_mgmt: ERROR, MCL_OPT_SET_NEXT_TOI failed for control session\n")) + } + /* + * Secondly, send the new TSI to clients... + */ + buf[0] = htonl(cur_TSI); + if ((ret = mcl_send(id[CTRL_IDX], &buf, sizeof(buf))) < 0) + EXIT(("server/ctrl_mgmt: ERROR, control session closed")) + /*printf("\t\ttest_rebootable_server: TSI msg sent on ctrl session\n");*/ +} + + +int +main (int argc, + char *argv[]) +{ + char buf[BUFLEN]; + int ret; + + port[CTRL_IDX] = 2000; /* in host format (required by MCL) */ + port[DATA_IDX] = 2100; + addr[CTRL_IDX] = ntohl(inet_addr("225.1.0.0")); /* in host format */ + /* (required by MCL) */ + addr[DATA_IDX] = ntohl(inet_addr("225.2.0.0")); + verbose[CTRL_IDX] = VERBOSITY_CTRL; + verbose[DATA_IDX] = VERBOSITY_DATA; + + printf("\ttest_rebootable_server: create and init two sessions...\n"); + setup_session(CTRL_IDX); + setup_session(DATA_IDX); + + /* + * start data transmission now. + */ + ctrl_mgmt(); + sprintf(buf, "this is an hello message sent on data session/TSI=%d", cur_TSI); + if ((ret = mcl_send(id[DATA_IDX], buf, strlen(buf)+1)) < 0) + EXIT(("server/main: data session closed\n")) + /* and now loop forever... */ + while (1) + sleep(1); + printf("\n\t... test_rebootable_server ok\n"); + return 0; +} + diff --git a/check/alc/test_reset_transmission b/check/alc/test_reset_transmission new file mode 100755 index 0000000..e5044b9 Binary files /dev/null and b/check/alc/test_reset_transmission differ diff --git a/check/alc/test_reset_transmission.c b/check/alc/test_reset_transmission.c new file mode 100644 index 0000000..e65579e --- /dev/null +++ b/check/alc/test_reset_transmission.c @@ -0,0 +1,153 @@ +/* $Id: test_reset_transmission.c,v 1.2 2005/02/25 14:13:09 moi Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 500 /* total number of sessions */ +#define BUFLEN 64 /* buffer size; not too large for */ + /* increased speed */ +#define VERBOSITY 0 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + int delivery_mode = DEL_MODE_ON_DEMAND; + float fec_ratio = 2.0; /* no need for a high fec ratio */ + int txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_LAN; + //int txprof_mode = MCL_TX_PROFILE_MID_RATE_INTERNET; + //int txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_INTERNET; + + printf("test_reset_transmission: test with %d successive resets...\n", SESSION_NB); + fflush(NULL); + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed\n"); + exit(-1); + } + err += mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio)); + if (err != 0) { + printf("ERROR: mcl_ctl FEC_RATIO failed\n"); + exit(-1); + } + err += mcl_ctl(id, MCL_OPT_TX_PROFILE, (void*)&txprof_mode, sizeof(txprof_mode)); + if (err) { + printf("ERROR: mcl_ctl TX_PROFILE failed\n"); + exit(-1); + } + err += mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + + err = mcl_ctl(id, MCL_OPT_DELIVERY_MODE, (void*)&delivery_mode, sizeof(delivery_mode)); + if (err != 0) { + printf("ERROR: mcl_ctl MCL_OPT_DELIVERY_MODE failed\n"); + exit(-1); + } + + + if((err = mcl_ctl(id, MCL_OPT_KEEP_DATA, NULL, 0)) <0) + { + printf("ERROR: MCL_OPT_KEEP_DATA failed\n"); + exit(-1); + } + + for (i = 0; i < BUFLEN; i++) + buf[i] = (char)i; + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + + if ((err = mcl_send(id, buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed for session %d\n", ses); + exit(-1); + } + if((err = mcl_ctl(id, MCL_OPT_RESET_TRANSMISSIONS, NULL, 0)) <0) + { + printf("ERROR: MCL_OPT_RESET_TRANSMISSIONS failed for session %d\n", ses); + exit(-1); + } + if((err = mcl_ctl(id, MCL_OPT_PUSH_DATA, NULL, 0)) <0) + { + printf("ERROR: MCL_OPT_PUSH_DATA failed for session %d\n", ses); + exit(-1); + } + if((err = mcl_ctl(id, MCL_OPT_KEEP_DATA, NULL, 0)) <0) + { + printf("ERROR: MCL_OPT_KEEP_DATA failed for session %d\n", ses); + exit(-1); + } + } + + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + + printf("\n... test_reset_transmission ok\n"); + return 0; +} + diff --git a/check/alc/test_reset_transmission.sh b/check/alc/test_reset_transmission.sh new file mode 100755 index 0000000..3c61005 --- /dev/null +++ b/check/alc/test_reset_transmission.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# +# $Id: test_reset_transmission.sh,v 1.2 2005/02/25 14:13:09 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test MCL with multiple reset tx sessions + +./test_reset_transmission +val=$? + +echo "returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +fi + +exit 0 diff --git a/check/alc/test_seq_of_tx_sessions b/check/alc/test_seq_of_tx_sessions new file mode 100755 index 0000000..6ecf337 Binary files /dev/null and b/check/alc/test_seq_of_tx_sessions differ diff --git a/check/alc/test_seq_of_tx_sessions.c b/check/alc/test_seq_of_tx_sessions.c new file mode 100644 index 0000000..1bbaf89 --- /dev/null +++ b/check/alc/test_seq_of_tx_sessions.c @@ -0,0 +1,123 @@ +/* $Id: test_seq_of_tx_sessions.c,v 1.2 2004/02/24 16:57:47 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test the creation/deletion of a long sequence of consecutive sessions + * to see if there is a fd leak + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 500 /* total number of sessions */ +#define BUFLEN 64 /* buffer size; not too large for */ + /* increased speed */ +#define VERBOSITY 0 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + float fec_ratio = 2.0; /* no need for a high fec ratio */ + int txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_LAN; + //int txprof_mode = MCL_TX_PROFILE_MID_RATE_INTERNET; + //int txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_INTERNET; + + printf("test_seq_of_tx_sessions: test with %d successive sending sessions...\n", SESSION_NB); + for (i = 0; i < BUFLEN; i++) + buf[i] = (char)i; + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + fflush(NULL); + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + err += mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio)); + if (err != 0) { + printf("ERROR: mcl_ctl FEC_RATIO failed for session %d\n", ses); + exit(-1); + } + err += mcl_ctl(id, MCL_OPT_TX_PROFILE, (void*)&txprof_mode, sizeof(txprof_mode)); + if (err) { + printf("ERROR: mcl_ctl TX_PROFILE failed for session %d\n", ses); + exit(-1); + } + err += mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + port += 10; /* incr port and addr */ + addr += 10; + if ((err = mcl_send(id, buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed for session %d\n", ses); + exit(-1); + } + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_seq_of_tx_sessions ok\n"); + return 0; +} + diff --git a/check/alc/test_seq_of_tx_sessions.sh b/check/alc/test_seq_of_tx_sessions.sh new file mode 100755 index 0000000..f0ad11b --- /dev/null +++ b/check/alc/test_seq_of_tx_sessions.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# +# $Id: test_seq_of_tx_sessions.sh,v 1.2 2004/12/21 14:43:48 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test MCL with multiple successive tx sessions + +./test_seq_of_tx_sessions +val=$? + +echo "returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +fi + +exit 0 diff --git a/check/alc/test_several_fec_codecs b/check/alc/test_several_fec_codecs new file mode 100755 index 0000000..b27d6b0 Binary files /dev/null and b/check/alc/test_several_fec_codecs differ diff --git a/check/alc/test_several_fec_codecs.c b/check/alc/test_several_fec_codecs.c new file mode 100644 index 0000000..bebf992 --- /dev/null +++ b/check/alc/test_several_fec_codecs.c @@ -0,0 +1,290 @@ +/* $Id: test_several_fec_codecs.c,v 1.7 2004/06/15 15:37:19 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_several_fec_codes.c, both sides... + * Principle: + * The source uses several FEC codecs, one per object. + * The receivers decodes each of them using the appropriate codec. + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include +#include "../../src/common/mcl_lib_api.h" + +//#define BUFLEN 200000 /* buffer size; must be large enough */ +#define BUFLEN 200003 /* buffer size; must be large enough */ + /* 200003 is a prime number, usefull */ + /* to better test the code */ +#define VERBOSITY_TX 0 /* verbosity level for sender */ +#define VERBOSITY_RX 0 /* verbosity level for receiver */ +#define NB_OBJECTS 8 /* total number of objects to tx */ + +int port = 2000; /* in host format */ +int verbose; +int ttl = 0; /* do not leave the host */ + + +void sender (void); +void receiver (void); +void init_buffer (char *buf); +void set_fec_ratios (int id, bool sender); + + +int +main (int argc, + char *argv[]) +{ + if (argc != 2) { + printf("test_several_fec_codes: ERROR: bad arg count %d; \"-send\" or \"-recv\" expected\n", argc); + exit(-1); + } + if (strncmp(argv[1], "-send", strlen("-send")) == 0) { + sender(); + } else if (strncmp(argv[1], "-recv", strlen("-recv")) == 0) { + receiver(); + } else { + printf("test_several_fec_codes: ERROR: unknown arg %s; \"-send\" or \"-recv\" expected\n", argv[1]); + exit(-1); + } + return 0; +} + + +void +sender () +{ + int id; + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* host format */ + int err; + char buf[BUFLEN]; + int codec_idx; /* fec codec to use */ + int sched; /* sched to use */ + int obj_count; + + printf("test_several_fec_codecs: SENDER\n"); + verbose = VERBOSITY_TX; + if ((id = mcl_open("w")) < 0) { + printf("test_several_fec_codes: ERROR: mcl_open failed for sender\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("test_several_fec_codes: ERROR: mcl_ctl PORT failed for sender\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("test_several_fec_codes: ERROR: mcl_ctl ADDR failed for sender\n"); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("test_several_fec_codes: ERROR: mcl_ctl VERBOSITY failed for sender\n"); + exit(-1); + } + } + err = mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("test_several_fec_codes: ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + set_fec_ratios(id, true); + /* + * use the basic scheduler, since with FEC_NULL there is no + * FEC DU at all, while schedulers 2 and 3 assume there are some! + */ + sched = MCL_SCHED_LCT1; + err = mcl_ctl(id, MCL_OPT_SCHED, (void*)&sched, sizeof(sched)); + if (err != 0) { + printf("test_several_fec_codes: ERROR: mcl_ctl MCL_OPT_SCHED failed for sender\n"); + exit(-1); + } + + /* fill in the buffer */ + init_buffer(buf); + + /* don't send immediately but wait... */ + err = mcl_ctl(id, MCL_OPT_KEEP_DATA, NULL, 0); + if (err != 0) { + printf("ERROR: mcl_ctl KEEP_DATA failed\n"); + exit(-1); + } + + /* submit all objects, changing the codec for each of them */ + codec_idx = MCL_FEC_SCHEME_NULL; /* start with NULL codec */ + for (obj_count = NB_OBJECTS; obj_count > 0; obj_count--) { + err = mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&codec_idx, + sizeof(codec_idx)); + if (err != 0) { + printf("WARNING: codec %d non-available... skipped\n", + codec_idx); + } else { + if ((err = mcl_send(id, buf, BUFLEN)) < 0) { + printf("test_several_fec_codes: ERROR: 1st mcl_send failed for sender\n"); + exit(-1); + } + printf("SENDER: object, %d bytes, with FEC %d encoding sent\n", err, codec_idx); + } + codec_idx = (codec_idx + 1) % MCL_FEC_SCHEME_NB; /* switch to following codec */ + } + + /* and now send... */ + err = mcl_ctl(id, MCL_OPT_PUSH_DATA, NULL, 0); + if (err != 0) { + printf("ERROR: mcl_ctl PUSH_DATA failed\n"); + exit(-1); + } + + if ((err = mcl_close(id)) < 0) { + printf("test_several_fec_codes: ERROR: mcl_close failed for sender\n"); + exit(-1); + } + printf("test_several_fec_codecs: SENDER ok\n"); + exit(0); +} + + +void +receiver () +{ + int id; + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* host format */ + int err; + char buf[BUFLEN]; /* buffer containing received data */ + char ref_buf[BUFLEN]; /* reference buffer */ + int i; + + printf("test_several_fec_codecs: RECEIVER\n"); + verbose = VERBOSITY_RX; + if ((id = mcl_open("r")) < 0) { + printf("test_several_fec_codes: ERROR: mcl_open failed for receiver\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("test_several_fec_codes: ERROR: mcl_ctl PORT failed for receiver\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("test_several_fec_codes: ERROR: mcl_ctl ADDR failed for receiver\n"); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("test_several_fec_codes: ERROR: mcl_ctl VERBOSITY failed for receiver\n"); + exit(-1); + } + } + /* no need to set FEC ratio at RX, carried in EXT_FTI header with + * most FEC codes */ + //set_fec_ratios(id, true); + + /* fill in the reference buffer */ + init_buffer(ref_buf); + + for (i = 0; ; i++) { + if ((err = mcl_recv(id, buf, BUFLEN)) < 0) { + break; /* finished */ + } + if (strncmp(buf, ref_buf, BUFLEN) != 0) { + printf("test_several_fec_codes: ERROR: bad object received\n"); + exit(-1); + } + printf("RECEIVER: object %d, %d bytes, received ok\n", i, err); + } + if ((err = mcl_close(id)) < 0) { + printf("test_several_fec_codes: ERROR: mcl_close failed for receiver\n"); + exit(-1); + } + printf("test_several_fec_codecs: RECEIVER ok\n"); + exit(0); +} + + +/* + * Fill in the buffer. + */ +void +init_buffer (char *buf) +{ + int *ptr; + int i; + + for (i = BUFLEN/4, ptr = (int*)buf; i > 0; i--, ptr++) { + *ptr = i; + } +} + + +/* + * Init the FEC ratios of the various FEC codes. + * Used by the sender and also by the receiver with the NULL and RSE codes. + */ +void +set_fec_ratios (int id, + bool sender) +{ + int codec_idx; /* fec codec to use */ + float fec_ratio; /* fec ratio to use */ + int err; + + for (codec_idx = MCL_FEC_SCHEME_NULL; + codec_idx < MCL_FEC_SCHEME_NB; + codec_idx++) { + if (sender == false && + codec_idx != MCL_FEC_SCHEME_NULL && + codec_idx != MCL_FEC_SCHEME_RSE_129_0) { + /* not required */ + continue; + } + err = mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&codec_idx, + sizeof(codec_idx)); + if (err != 0) { + //printf("WARNING: codec %d non-available... skipped\n", + // codec_idx); + continue; + } + fec_ratio = 1.5; + err = mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio)); + if (err != 0) { + printf("test_several_fec_codes: ERROR: mcl_ctl MCL_OPT_FEC_RATIO failed for %s\n", (sender ? "sender" : "receiver")); + exit(-1); + } + } +} diff --git a/check/alc/test_several_fec_codecs.sh b/check/alc/test_several_fec_codecs.sh new file mode 100755 index 0000000..0b7ce9c --- /dev/null +++ b/check/alc/test_several_fec_codecs.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# +# $Id: test_several_fec_codecs.sh,v 1.3 2004/12/21 14:43:48 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# Principle: +# The source uses several FEC codecs, one per object. +# The receivers decodes each of them using the appropriate codec. + +#./test_several_fec_codecs -recv > /tmp/test_several_fec_codecs_rx.trc 2>&1 & +./test_several_fec_codecs -recv & +recv_pid=$! + +#./test_several_fec_codecs -send > /tmp/test_several_fec_codecs_tx.trc 2>&1 & +./test_several_fec_codecs -send & +send_pid=$! + +wait ${recv_pid} +recv_val=$? + +wait ${send_pid} +send_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "test several FEC codecs (sender) failed" + exit 1 +elif [ ${recv_val} -ne 0 ] +then + echo "test several FEC codecs (receiver) failed" + exit 1 +fi diff --git a/check/alc/test_stop_tx_one_adu b/check/alc/test_stop_tx_one_adu new file mode 100755 index 0000000..eaa6fcf Binary files /dev/null and b/check/alc/test_stop_tx_one_adu differ diff --git a/check/alc/test_stop_tx_one_adu.c b/check/alc/test_stop_tx_one_adu.c new file mode 100644 index 0000000..01afeb2 --- /dev/null +++ b/check/alc/test_stop_tx_one_adu.c @@ -0,0 +1,139 @@ +/* $Id: test_stop_tx_one_adu.c,v 1.2 2005/03/01 11:03:22 moi Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define OBJECT_NB 500 /* total number of objects */ +#define NB_STOPPED 50 /* number of objects to stop tx */ +#define BUFLEN 64 /* buffer size; not too large for */ + /* increased speed */ +#define VERBOSITY 0 /* verbosity level */ +#define SEED 2334 + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* in host format! */ + int err; + int obj; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + float fec_ratio = 2.0; /* no need for a high fec ratio */ + int txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_LAN; + //int txprof_mode = MCL_TX_PROFILE_MID_RATE_INTERNET; + //int txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_INTERNET; + + printf("test_stop_tx_one_adu: test with %d successive stops...\n", NB_STOPPED); + fflush(NULL); + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed\n"); + exit(-1); + } + err += mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio)); + if (err != 0) { + printf("ERROR: mcl_ctl FEC_RATIO failed\n"); + exit(-1); + } + err += mcl_ctl(id, MCL_OPT_TX_PROFILE, (void*)&txprof_mode, sizeof(txprof_mode)); + if (err) { + printf("ERROR: mcl_ctl TX_PROFILE failed\n"); + exit(-1); + } + err += mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + + for (i = 0; i < BUFLEN; i++) + buf[i] = (char)i; + for (obj = 0; obj < OBJECT_NB; obj++) { + + if ((err = mcl_send(id, buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed\n"); + exit(-1); + } + + } + + /* Now randomly cancel NB_STOPPED of them */ + srand(SEED); + UINT64 toi; + for (obj = 0; obj < NB_STOPPED; obj++) { + toi =(rand()% (NB_STOPPED - 1)) + 1; + printf(" %d ", toi); + if((err = mcl_ctl(id, MCL_OPT_STOP_TRANSMITTING_ADU, (void *)&toi, sizeof(toi))) <0) + { + printf("ERROR: MCL_OPT_STOP_TRANSMITTING_ADU failed for object %d\n", toi); + exit(-1); + } + } + + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed\n"); + exit(-1); + } + + printf("\n... test_reset_transmission ok\n"); + return 0; +} + diff --git a/check/alc/test_stop_tx_one_adu.sh b/check/alc/test_stop_tx_one_adu.sh new file mode 100755 index 0000000..76957bf --- /dev/null +++ b/check/alc/test_stop_tx_one_adu.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# +# $Id: test_stop_tx_one_adu.sh,v 1.1 2005/02/25 14:13:10 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test MCL with multiple stop tx for one adu + +./test_stop_tx_one_adu +val=$? + +echo "returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +fi + +exit 0 diff --git a/check/alc/test_vtm.sh b/check/alc/test_vtm.sh new file mode 100755 index 0000000..6e0e3e6 --- /dev/null +++ b/check/alc/test_vtm.sh @@ -0,0 +1,56 @@ +#!/bin/sh +# +# $Id: test_vtm.sh,v 1.2 2004/12/21 14:43:48 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test the MCL with an application that uses two sessions +# each of them using the Virtual Tx Memory service +# An object is sent on each session, containing the session value. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + + +#./test_vtm_rx > /tmp/mcl_vtm_rx.trc 2>&1 & +./test_vtm_rx & +recv_pid=$! + +#./test_vtm_tx > /tmp/mcl_vtm_tx.trc 2>&1 & +./test_vtm_tx & +send_pid=$! + +wait ${recv_pid} +recv_val=$? + +wait ${send_pid} +send_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "VTM (Virtual Tx Memory service) send failed" + exit 1 +elif [ ${recv_val} -ne 0 ] +then + echo "VTM (Virtual Tx Memory service) recv failed" + exit 1 +fi diff --git a/check/alc/test_vtm_rx b/check/alc/test_vtm_rx new file mode 100755 index 0000000..abcab0a Binary files /dev/null and b/check/alc/test_vtm_rx differ diff --git a/check/alc/test_vtm_rx.c b/check/alc/test_vtm_rx.c new file mode 100644 index 0000000..28b2e6b --- /dev/null +++ b/check/alc/test_vtm_rx.c @@ -0,0 +1,137 @@ +/* $Id: test_vtm_rx.c,v 1.2 2004/02/24 16:57:53 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_vtm_rx.c + * open two sessions, use the VTM service, and check what has been received + * receiver side version... + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 2 /* 2 sessions max */ +#define BUFLEN 150000 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int port[SESSION_NB] = {2000, 2100}; /* in host format! */ + unsigned long addr[SESSION_NB] = { + ntohl(inet_addr("225.1.0.0")), + ntohl(inet_addr("225.2.0.0"))}; /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + int unset = 0; /* unset value for mcl_ctl */ + + printf("\ttest_vtm_rx: create %d receiving sessions...\n\t", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("r")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port[ses], sizeof(*port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr[ses], sizeof(*addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + /* diseable VTM as we are a receiver... */ + err = mcl_ctl(id[ses], MCL_OPT_VIRTUAL_TX_MEMORY, (void*)&unset, sizeof(unset)); + if (err != 0) { + printf("ERROR: mcl_ctl VIRTUAL_TX_MEMORY: not supported, ignore test...\n"); + exit(0); + } + + } + + printf("\n\ttest_vtm_rx: finish the init of the %d sessions...\n\t", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + if ((err = mcl_recv(id[ses], NULL, 0)) < 0) { + printf("ERROR: empty mcl_recv failed for session %d\n", ses); + exit(-1); + } + } + + printf("\n\ttest_vtm_rx: read on the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf("\trecv on session %d... ", ses); + if ((err = mcl_recv(id[ses], buf, BUFLEN)) < 0) { + printf("ERROR: mcl_recv failed for session %d\n", ses); + exit(-1); + } + for (i = 0; i < BUFLEN; i++) { + /* all bytes should be equal to ses */ + if (buf[i] != ses) { + printf("ERROR: bad value in received buffer (got %d, expected %d)\n", + buf[i], ses); + exit(-1); + } + } + } + + printf("\n\ttest_vtm_rx: close the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf("\tclose session %d... ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n\t... test_vtm_rx ok\n"); + return 0; +} + diff --git a/check/alc/test_vtm_tx b/check/alc/test_vtm_tx new file mode 100755 index 0000000..8867bd8 Binary files /dev/null and b/check/alc/test_vtm_tx differ diff --git a/check/alc/test_vtm_tx.c b/check/alc/test_vtm_tx.c new file mode 100644 index 0000000..a6416cb --- /dev/null +++ b/check/alc/test_vtm_tx.c @@ -0,0 +1,137 @@ +/* $Id: test_vtm_tx.c,v 1.2 2004/02/24 16:57:55 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_vtm_tx.c + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include /* for memset */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 2 /* 2 sessions max */ +#define BUFLEN 150000 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int port[SESSION_NB] = {2000, 2100}; /* in host format! */ + unsigned long addr[SESSION_NB] = { + ntohl(inet_addr("225.1.0.0")), + ntohl(inet_addr("225.2.0.0"))}; /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int verbose = VERBOSITY; + int set = 1; /* set value for mcl_ctl */ + + printf("test_vtm_tx: create %d sending sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port[ses], sizeof(*port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr[ses], sizeof(*addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + err = mcl_ctl(id[ses], MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_VIRTUAL_TX_MEMORY, (void*)&set, sizeof(set)); + if (err != 0) { + printf("ERROR: mcl_ctl VIRTUAL_TX_MEMORY: not supported, ignore test...\n"); + exit(0); + } + /* don't send immediately but wait... */ + err = mcl_ctl(id[ses], MCL_OPT_KEEP_DATA, NULL, 0); + if (err != 0) { + printf("ERROR: mcl_ctl KEEP_DATA failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_vtm_tx: finish the init of the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + memset(buf, ses, BUFLEN); /* init buffer with session # */ + if ((err = mcl_send(id[ses], buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_vtm_tx: write on the %d sessions...\n", SESSION_NB); + /* ...and now send everything */ + for (ses = 0; ses < SESSION_NB; ses++) { + err = mcl_ctl(id[ses], MCL_OPT_PUSH_DATA, NULL, 0); + if (err != 0) { + printf("ERROR: mcl_ctl PUSH_DATA failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_vtm_tx: close the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_vtm_tx ok\n"); + return 0; +} + diff --git a/check/alc/test_wait_rx.sh b/check/alc/test_wait_rx.sh new file mode 100755 index 0000000..a313baa --- /dev/null +++ b/check/alc/test_wait_rx.sh @@ -0,0 +1,63 @@ +#!/bin/sh +# +# $Id: test_wait_rx.sh,v 1.2 2004/12/21 14:43:48 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Vincent Roca - vincent.roca@inrialpes.fr +# Julien Laboure - julien.laboure@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# +# test the wait_event at the receiver +# + + +# +# scenario 1: +# The source tx a single ADU, waits the end (wait event), +# then issues a close. +# The receiver receives this ADU, waits the end (wait event), +# then issues a close. +# + +recv_val=1 +send_val=1 + +./test_wait_rx_sender & +recv_pid=$! +./test_wait_rx_receiver & +send_pid=$! + +wait ${recv_pid} +recv_val=$? + +wait ${send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + + +if [ ${send_val} -ne 0 ] +then + echo "wait_rx Send Failed" + exit 1 +elif [ ${recv_val} -ne 0 ] +then + echo "wait_rx Recv Failed" + exit 1 +fi + diff --git a/check/alc/test_wait_rx_receiver b/check/alc/test_wait_rx_receiver new file mode 100755 index 0000000..6211245 Binary files /dev/null and b/check/alc/test_wait_rx_receiver differ diff --git a/check/alc/test_wait_rx_receiver.c b/check/alc/test_wait_rx_receiver.c new file mode 100644 index 0000000..bec15e7 --- /dev/null +++ b/check/alc/test_wait_rx_receiver.c @@ -0,0 +1,111 @@ +/* $Id: test_wait_rx_receiver.c,v 1.3 2004/11/29 17:07:27 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_wait_tx.c + */ + + +#include + + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define BUFLEN 4096 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + +int +main (int argc, + char *argv[]) +{ + int id; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* in host format! */ + int err; + char buf[BUFLEN]; + int verbose = VERBOSITY; + int never_leave_base_layer = 1; + + if ((id = mcl_open("r")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_NEVER_LEAVE_BASE_LAYER, + (void*)&never_leave_base_layer, + sizeof(never_leave_base_layer)); + if (err != 0) { + printf("ERROR: mcl_ctl NEVER_LEAVE_BASE_LAYER failed\n"); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed\n"); + exit(-1); + } + } + printf("\nreceiver: recv\n"); + if ((err = mcl_recv(id, buf, BUFLEN)) < 0) { + printf("ERROR: mcl_recv failed\n"); + exit(-1); + } + printf("\nreceiver: wait end of rx now...\n"); + if ((err = mcl_wait_event(id, MCL_WAIT_EVENT_END_RX)) < 0) { + printf("ERROR: mcl_wait_event END_RX failed\n"); + exit(-1); + } + printf("\nreceiver: ... wait returns, all rx must be finished...\n"); + printf("\nreceiver: wait CLOSE msg now...\n"); + if ((err = mcl_wait_event(id, MCL_WAIT_EVENT_CLOSED)) < 0) { + printf("ERROR: mcl_wait_event CLOSED failed\n"); + exit(-1); + } + printf("\nreceiver: ... wait returns, CLOSE received...\n"); + printf("\nreceiver: close\n"); + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed\n"); + exit(-1); + } + return 0; +} diff --git a/check/alc/test_wait_rx_sender b/check/alc/test_wait_rx_sender new file mode 100755 index 0000000..1d1396e Binary files /dev/null and b/check/alc/test_wait_rx_sender differ diff --git a/check/alc/test_wait_rx_sender.c b/check/alc/test_wait_rx_sender.c new file mode 100644 index 0000000..54e8c01 --- /dev/null +++ b/check/alc/test_wait_rx_sender.c @@ -0,0 +1,106 @@ +/* $Id: test_wait_rx_sender.c,v 1.2 2004/02/24 16:58:01 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_wait_tx.c + */ + + +#include + + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define BUFLEN 4096 /* buffer size */ +#define VERBOSITY 0 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* in host format! */ + int err; + char buf[BUFLEN]; + int verbose = VERBOSITY; + + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed\n"); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed\n"); + exit(-1); + } + } + err = mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + printf("\nsender: write\n"); + if ((err = mcl_send(id, buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed\n"); + exit(-1); + } + printf("\nsender: wait now...\n"); + if ((err = mcl_wait_event(id, MCL_WAIT_EVENT_END_TX)) < 0) { + printf("ERROR: mcl_wait_event END_TX failed\n"); + exit(-1); + } + printf("\n\n!!!sender: ... wait returns, all tx must be finished..."); + printf("\nsender: close\n"); + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed\n"); + exit(-1); + } + return 0; +} + diff --git a/check/alc/test_wait_tx b/check/alc/test_wait_tx new file mode 100755 index 0000000..5690e5b Binary files /dev/null and b/check/alc/test_wait_tx differ diff --git a/check/alc/test_wait_tx.c b/check/alc/test_wait_tx.c new file mode 100644 index 0000000..f55a5b9 --- /dev/null +++ b/check/alc/test_wait_tx.c @@ -0,0 +1,110 @@ +/* $Id: test_wait_tx.c,v 1.2 2004/02/24 16:58:04 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_wait_tx.c + */ + +#include + +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 50 /* number of sessions */ +#define BUFLEN 4096 /* buffer size */ +#define VERBOSITY 1 /* verbosity level */ + +int ttl = 0; /* do not leave the host */ + + +int +main (int argc, + char *argv[]) +{ + int id; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("225.1.0.0")); /* in host format! */ + int err; + char buf[BUFLEN]; + int verbose = VERBOSITY; + + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed\n"); + exit(-1); + } + err = mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed\n"); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed\n"); + exit(-1); + } + } + err = mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed\n"); + exit(-1); + } + printf("\ntest_wait_tx: write\n"); + if ((err = mcl_send(id, buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed\n"); + exit(-1); + } + printf("\ntest_wait_tx: write\n"); + if ((err = mcl_send(id, buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed\n"); + exit(-1); + } + printf("\ntest_wait_tx: wait now...\n"); + if ((err = mcl_wait_event(id, MCL_WAIT_EVENT_END_TX)) < 0) { + printf("ERROR: mcl_wait_event failed\n"); + exit(-1); + } + printf("\n\n!!!test_wait_tx: ... wait returns, all tx must be finished...\n!!!check it visually...\n\n"); + printf("\ntest_wait_tx: close now...\n"); + if ((err = mcl_close(id)) < 0) { + printf("ERROR: mcl_close failed\n"); + exit(-1); + } + return 0; +} + diff --git a/check/alc/test_wait_tx.sh b/check/alc/test_wait_tx.sh new file mode 100755 index 0000000..dc0ae0b --- /dev/null +++ b/check/alc/test_wait_tx.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# +# $Id: test_wait_tx.sh,v 1.2 2004/12/21 14:43:49 roca Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test the MCL with an application that waits till all +# DUs are sent before closing. + +./test_wait_tx +val=$? + +echo "returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +else + exit 0 +fi + diff --git a/check/alc/wincheck/test_abort.vcproj b/check/alc/wincheck/test_abort.vcproj new file mode 100644 index 0000000..8e5d939 --- /dev/null +++ b/check/alc/wincheck/test_abort.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_demux_label1_rx.vcproj b/check/alc/wincheck/test_demux_label1_rx.vcproj new file mode 100644 index 0000000..834728b --- /dev/null +++ b/check/alc/wincheck/test_demux_label1_rx.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_demux_label1_tx.vcproj b/check/alc/wincheck/test_demux_label1_tx.vcproj new file mode 100644 index 0000000..f139468 --- /dev/null +++ b/check/alc/wincheck/test_demux_label1_tx.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_multi_sessions1.vcproj b/check/alc/wincheck/test_multi_sessions1.vcproj new file mode 100644 index 0000000..af812ee --- /dev/null +++ b/check/alc/wincheck/test_multi_sessions1.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_multi_sessions2.vcproj b/check/alc/wincheck/test_multi_sessions2.vcproj new file mode 100644 index 0000000..d951fc0 --- /dev/null +++ b/check/alc/wincheck/test_multi_sessions2.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_no_tx.vcproj b/check/alc/wincheck/test_no_tx.vcproj new file mode 100644 index 0000000..44d66f3 --- /dev/null +++ b/check/alc/wincheck/test_no_tx.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_vtm_rx.vcproj b/check/alc/wincheck/test_vtm_rx.vcproj new file mode 100644 index 0000000..cc511e2 --- /dev/null +++ b/check/alc/wincheck/test_vtm_rx.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_vtm_tx.vcproj b/check/alc/wincheck/test_vtm_tx.vcproj new file mode 100644 index 0000000..67f5dca --- /dev/null +++ b/check/alc/wincheck/test_vtm_tx.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_wait_rx_receiver.vcproj b/check/alc/wincheck/test_wait_rx_receiver.vcproj new file mode 100644 index 0000000..484082d --- /dev/null +++ b/check/alc/wincheck/test_wait_rx_receiver.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_wait_rx_sender.vcproj b/check/alc/wincheck/test_wait_rx_sender.vcproj new file mode 100644 index 0000000..7fc4a92 --- /dev/null +++ b/check/alc/wincheck/test_wait_rx_sender.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/test_wait_tx.vcproj b/check/alc/wincheck/test_wait_tx.vcproj new file mode 100644 index 0000000..2be3144 --- /dev/null +++ b/check/alc/wincheck/test_wait_tx.vcproj @@ -0,0 +1,136 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/alc/wincheck/wincheck.cpp b/check/alc/wincheck/wincheck.cpp new file mode 100755 index 0000000..2ab4619 --- /dev/null +++ b/check/alc/wincheck/wincheck.cpp @@ -0,0 +1,585 @@ +/* $Id: wincheck.cpp,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ */ +/* + * Copyright (c) 1999-2001 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * Wincheck.cpp + * + * MCL validation tool for Windows Platforms + */ + + +#include +#include +#include +#include + +using namespace std; + + + +#define nbTests 9 +#define TestnameLen 30 + +char SomeTests[nbTests][TestnameLen]; +char WorkDir[_MAX_PATH]; + +int test_abort(); +int test_demux_label(); +int test_fcast_mcl_modes(); +int test_fcast_xfert(); +int test_fcast_single_xfert(); +int test_multi_sessions(); +int test_no_tx(); +int test_vtm(); +int test_wait_rx(); +int test_wait_tx(); + + +void initTests() +{ + strncpy(SomeTests[0], "test_abort", TestnameLen); + strncpy(SomeTests[1], "test_demux_label", TestnameLen); + strncpy(SomeTests[2], "test_fcast_mcl_modes", TestnameLen); + strncpy(SomeTests[3], "test_fcast_xfert", TestnameLen); + strncpy(SomeTests[4], "test_fcast_single_xfert", TestnameLen); + strncpy(SomeTests[5], "test_multi_sessions", TestnameLen); + strncpy(SomeTests[6], "test_no_tx", TestnameLen); + strncpy(SomeTests[7], "test_vtm", TestnameLen); + strncpy(SomeTests[8], "test_wait_rx", TestnameLen); + strncpy(SomeTests[9], "test_wait_tx", TestnameLen); + + _getcwd( WorkDir, _MAX_PATH); +} + + +int ExecTest(int indice) +{ + int res = -1; + _chdir(WorkDir); + + switch(indice) + { + case 0: + res = test_abort(); + break; + + case 1: + res = test_demux_label(); + break; + case 2: + res = test_fcast_mcl_modes(); + break; + case 3: + res = test_fcast_xfert(); + break; + case 4: + res = test_fcast_single_xfert(); + break; + case 5: + res = test_multi_sessions(); + break; + case 6: + res = test_no_tx(); + break; + case 7: + res = test_vtm(); + break; + case 8: + res = test_wait_rx(); + break; + case 9: + res = test_wait_tx(); + break; + default: + res=1; + break; + + } + return res; +} + + + +int main(int argc, char* argv[]) +{ + int result = -1; + initTests(); + + for(int i=0; i Running Test " << SomeTests[i] << endl; + result = ExecTest(i); + if(result !=0) + { + cout << endl << "****** ERROR: Test " << SomeTests[i] << " failed! Aborting... ******" << endl; + exit(-1); + } + else + { + cout << "<------ Test " << SomeTests[i] << ": Success!!!" << endl; + } + } + + cout << endl <<"****** All tests succeeded! Validation OK. ******" << endl; + system("pause"); + return 0; +} + + + +// Test the MCL with an application that opens/sends/aborts +int test_abort() +{ + return _spawnl(_P_WAIT, "test_abort", "test_abort", NULL); +} + + + +// test the MCL with an application that uses different sessions +// with different demux labels. +// An object is sent on each session, containing the demux label value. +int test_demux_label() +{ + int pid1, pid2 = -1; + int res = -1; + +// cout<<"WARNING: test skipped !!!!!!"; +// return 0; + + + pid1 = _spawnl(_P_NOWAIT, "test_demux_label1_rx", "test_demux_label1_rx", NULL); + pid2 = _spawnl(_P_NOWAIT, "test_demux_label1_tx", "test_demux_label1_tx", NULL); + + if(pid1==-1 || pid2==-1) + { + cout << "_spawnl Failure in test_demux_label" << endl; + return -1; + } + + if( _cwait( &res, pid1, NULL)!=pid1 || res!=0 ) // Error RX!! + { + cout << "DEMUX_LABEL Recv Failed" << endl; + return -1; + } + if( _cwait( &res, pid2, NULL)!=pid2 || res!=0 ) // Error TX! + { + cout << "DEMUX_LABEL Send Failed" << endl; + return -1; + } + return res; +} + + + + +int test_fcast_mcl_modes() +{ + int pid1, pid2 = -1; + int res = 0; + + char *file="./Other_Files/i-am-a-BIG.file"; + + + cout < + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/check/flute/Makefile b/check/flute/Makefile new file mode 100644 index 0000000..c3e7d96 --- /dev/null +++ b/check/flute/Makefile @@ -0,0 +1,164 @@ +# $Id: Makefile,v 1.2 2005/05/12 16:03:17 moi Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Makefile.common as appropriate +include ../../Makefile.common + + + +# libraries required +ifeq (${OS},linux) + # Linux version + # + BINDIR = ../../bin/linux + LDPC_BINDIR = ../../../ldpc/bin/linux + XERCES_DIR = ../../../xerces-c + # Shared version (default) + LIBRARIES = -lc -lm -lpthread + #-lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},solaris) + # Solaris version: + # Warning: SUN recommends to have -lucb at the end of list, + # in order to priviledge SUN's libs to the BSD compatibility + # lib (libucb). + # CC requires: -mt -lpthread for multithreaded applications + # OpenSSL is installed at /usr/local/ssl in our system. Update if + # needed. + # + BINDIR = ../../bin/solaris + LDPC_BINDIR = ../../../ldpc/bin/solaris + XERCES_DIR = ../../../xerces-c + OPENSSL_DIR = /usr/local/ssl + LIBRARIES = -lc -lm -lsocket -lnsl -lposix4 -mt -lpthread -L/usr/ucblib -lucb -L${OPENSSL_DIR}/lib -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include -I${OPENSSL_DIR}/include +endif + +ifeq (${OS},freebsd) + # FreeBSD version: + # CC requires: -mt -lpthread for multithreaded applications + # + BINDIR = ../../bin/freebsd + LDPC_BINDIR = ../../../ldpc/bin/freebsd + XERCES_DIR = ../../../xerces-c + LIBRARIES = -lm -pthread -L/usr/local/lib -lcrypto + #ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include + ADD_INCLUDES = -I${XERCES_DIR}/include +endif + +ifeq (${OS},aix) + # AIX version + BINDIR = ../../bin/aix + LDPC_BINDIR = ../../../ldpc/bin/aix + XERCES_DIR = ../../../xerces-c + LIBRARIES = -lm -pthread -lc -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},hp-ux) + # HP-UX version + BINDIR = ../../bin/hp-ux + LDPC_BINDIR = ../../../ldpc/bin/hp-ux + XERCES_DIR = ../../../xerces-c + LIBRARIES = -lc -lm -pthread -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},irix) + # IRIX version + BINDIR = ../../bin/irix + LDPC_BINDIR = ../../../ldpc/bin/irix + XERCES_DIR = ../../../xerces-c + LIBRARIES = -lc -lm -pthread -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +CFLAGS = -O -g -DALC ${OSFLAGS} + +# cc version +# -fullwarn for IRIX c compiler +#CFLAGS = -O -fullwarn -DALC ${OSFLAGS} + +# add purify linker for memory debug (Solaris only). +# Purify 4.0 Solaris 2, Copyright (C) 1992-1996 Pure Software Inc. +# +#CCLINK_PURE = purify $(CC) +CCLINK_PURE = purify -cache-dir=/tmp $(CC) + +# XML parsing library +# choose between the static / dynamic (default) xerces-c versions. +LIBRARIES := ${LIBRARIES} -lxerces-c -lxerces-depdom +LIBRARIES := ${LIBRARIES} ${XERCES_DIR}/lib/libxerces-c.a + +# Other libraries +MCL_LIBRARY = ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +SDP_LIBRARY = ${BINDIR}/libsinistersdp.a +FLUTE_LIBRARY = ${BINDIR}/libflute.a + + +# List of source and object test files +SRCFILES = test_open_close.cpp +OFILES = ${SRCFILES:.cpp=.o} +TARGETS = ${SRCFILES:.cpp=} + + + +###### Dependancies ###### + +all: ${TARGETS} + +# Rule for C++ .cpp extension +.cpp.o: + $(CC) -c $(CFLAGS) -o $*.o $*.cpp + +test_open_close: test_open_close.o ${FLUTE_LIBRARY} + ${CC} ${CFLAGS} test_open_close.o ${LIBRARIES} ${FLUTE_LIBRARY} ${SDP_LIBRARY} ${MCL_LIBRARY} -o test_open_close + #strip test_open_close + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in core ${TARGETS} ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +test_open_close.o: ../../src/flute_lib/FluteAPI.h +test_open_close.o: ../../src/common/mcl_lib_api.h +test_open_close.o: ../../src/common/mcl_types.h +test_open_close.o: ../../src/alc/mcl_lib_api_alc.h +test_open_close.o: ../../src/flute_lib/Flute.h +test_open_close.o: ../../src/flute_lib/FluteReceiver.h +test_open_close.o: ../../src/flute_lib/FluteSender.h +test_open_close.o: ../../src/flute_lib/FluteFileInfo.h +test_open_close.o: ../../src/flute_lib/FluteFileDeliveryCarousel.h diff --git a/check/flute/files/fdt_tsi1.xml b/check/flute/files/fdt_tsi1.xml new file mode 100644 index 0000000..3a2a51c --- /dev/null +++ b/check/flute/files/fdt_tsi1.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + diff --git a/check/flute/files/recv/2_Bytes_File b/check/flute/files/recv/2_Bytes_File new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/check/flute/files/recv/2_Bytes_File @@ -0,0 +1 @@ +2 diff --git a/check/flute/files/recv/3_Bytes_File b/check/flute/files/recv/3_Bytes_File new file mode 100644 index 0000000..ff3eb13 --- /dev/null +++ b/check/flute/files/recv/3_Bytes_File @@ -0,0 +1 @@ +3! diff --git a/check/flute/files/recv/4_Bytes_File b/check/flute/files/recv/4_Bytes_File new file mode 100644 index 0000000..1e6fd03 --- /dev/null +++ b/check/flute/files/recv/4_Bytes_File @@ -0,0 +1 @@ +444 diff --git a/check/flute/files/recv/Other_Files/i-am-a-BIG.file b/check/flute/files/recv/Other_Files/i-am-a-BIG.file new file mode 100644 index 0000000..8366245 --- /dev/null +++ b/check/flute/files/recv/Other_Files/i-am-a-BIG.file @@ -0,0 +1,64 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" \ No newline at end of file diff --git a/check/flute/files/recv/Other_Files/i-am-a.file b/check/flute/files/recv/Other_Files/i-am-a.file new file mode 100644 index 0000000..00cac6a --- /dev/null +++ b/check/flute/files/recv/Other_Files/i-am-a.file @@ -0,0 +1,95 @@ +# $Id: i-am-a.file,v 1.1 2005/05/12 16:15:08 moi Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Rules.mk + + +# libraries required +ifeq (${OS},linux) + # Linux version + # MCL library requires -lpthread + # + BINDIR = ../bin/linux + LIBRARIES = -lc -lm -lpthread ${BINDIR}/libmcl.a +endif + +ifeq (${OS},solaris) + # Solaris version: requires -lsocket -lnsl and -L/usr/ucblib -lucb + # + BINDIR = ../bin/solaris + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -lpthread ${BINDIR}/libmcl.a +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +CFLAGS = -O -g ${OSFLAGS} + +# cc version +# -fullwarn for IRIX c compiler +#CFLAGS = -O -fullwarn ${OSFLAGS} + +SRCFILES = test_no_tx.c +OFILES = test_no_tx.o +TARGETS = test_no_tx + + +###### Dependancies ###### + +all: ${TARGETS} + +test_no_tx: test_no_tx.o ${BINDIR}/libmcl.a + ${CC} ${CFLAGS} test_no_tx.o ${LIBRARIES} -o test_no_tx + strip test_no_tx + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in core ${TARGETS} ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # use -p to say that objects are in the bin dir + # ${DEPEND} -pbin/ -- ${CFLAGS} -- ${SRCFILES} + ${DEPEND} -- ${CFLAGS} -- ${SRCFILES} + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +test_no_tx.o: /usr/include/stdio.h /usr/include/features.h +test_no_tx.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +test_no_tx.o: /usr/include/bits/types.h /usr/include/libio.h +test_no_tx.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +test_no_tx.o: /usr/include/netinet/in.h /usr/include/limits.h +test_no_tx.o: /usr/include/bits/posix1_lim.h /usr/include/bits/local_lim.h +test_no_tx.o: /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h +test_no_tx.o: /usr/include/stdint.h /usr/include/bits/wordsize.h +test_no_tx.o: /usr/include/sys/types.h /usr/include/time.h +test_no_tx.o: /usr/include/endian.h /usr/include/bits/endian.h +test_no_tx.o: /usr/include/sys/select.h /usr/include/bits/select.h +test_no_tx.o: /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h +test_no_tx.o: /usr/include/bits/socket.h /usr/include/bits/sockaddr.h +test_no_tx.o: /usr/include/asm/socket.h /usr/include/asm/sockios.h +test_no_tx.o: /usr/include/bits/in.h /usr/include/bits/byteswap.h +test_no_tx.o: ../src/mcl_lib.h diff --git a/check/flute/files/recv/fdt_tsi1.xml b/check/flute/files/recv/fdt_tsi1.xml new file mode 100644 index 0000000..648b0ba --- /dev/null +++ b/check/flute/files/recv/fdt_tsi1.xml @@ -0,0 +1,7 @@ + + + + diff --git a/check/flute/files/send/2_Bytes_File b/check/flute/files/send/2_Bytes_File new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/check/flute/files/send/2_Bytes_File @@ -0,0 +1 @@ +2 diff --git a/check/flute/files/send/3_Bytes_File b/check/flute/files/send/3_Bytes_File new file mode 100644 index 0000000..ff3eb13 --- /dev/null +++ b/check/flute/files/send/3_Bytes_File @@ -0,0 +1 @@ +3! diff --git a/check/flute/files/send/4_Bytes_File b/check/flute/files/send/4_Bytes_File new file mode 100644 index 0000000..1e6fd03 --- /dev/null +++ b/check/flute/files/send/4_Bytes_File @@ -0,0 +1 @@ +444 diff --git a/check/flute/files/send/Other_Files/i-am-a-BIG.file b/check/flute/files/send/Other_Files/i-am-a-BIG.file new file mode 100644 index 0000000..8366245 --- /dev/null +++ b/check/flute/files/send/Other_Files/i-am-a-BIG.file @@ -0,0 +1,64 @@ +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""Content-Base:fcast_test/send/Other_Files/ +Content-Location:i-am-a-BIG.file +Content-Filesize:220000 +Content-Length:220000 +Content-Fragment:1/1 +Content-Offset:0 +¥ +?"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" \ No newline at end of file diff --git a/check/flute/files/send/Other_Files/i-am-a.file b/check/flute/files/send/Other_Files/i-am-a.file new file mode 100644 index 0000000..00cac6a --- /dev/null +++ b/check/flute/files/send/Other_Files/i-am-a.file @@ -0,0 +1,95 @@ +# $Id: i-am-a.file,v 1.1 2005/05/12 16:15:08 moi Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Rules.mk + + +# libraries required +ifeq (${OS},linux) + # Linux version + # MCL library requires -lpthread + # + BINDIR = ../bin/linux + LIBRARIES = -lc -lm -lpthread ${BINDIR}/libmcl.a +endif + +ifeq (${OS},solaris) + # Solaris version: requires -lsocket -lnsl and -L/usr/ucblib -lucb + # + BINDIR = ../bin/solaris + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -lpthread ${BINDIR}/libmcl.a +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +CFLAGS = -O -g ${OSFLAGS} + +# cc version +# -fullwarn for IRIX c compiler +#CFLAGS = -O -fullwarn ${OSFLAGS} + +SRCFILES = test_no_tx.c +OFILES = test_no_tx.o +TARGETS = test_no_tx + + +###### Dependancies ###### + +all: ${TARGETS} + +test_no_tx: test_no_tx.o ${BINDIR}/libmcl.a + ${CC} ${CFLAGS} test_no_tx.o ${LIBRARIES} -o test_no_tx + strip test_no_tx + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in core ${TARGETS} ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # use -p to say that objects are in the bin dir + # ${DEPEND} -pbin/ -- ${CFLAGS} -- ${SRCFILES} + ${DEPEND} -- ${CFLAGS} -- ${SRCFILES} + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +test_no_tx.o: /usr/include/stdio.h /usr/include/features.h +test_no_tx.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +test_no_tx.o: /usr/include/bits/types.h /usr/include/libio.h +test_no_tx.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +test_no_tx.o: /usr/include/netinet/in.h /usr/include/limits.h +test_no_tx.o: /usr/include/bits/posix1_lim.h /usr/include/bits/local_lim.h +test_no_tx.o: /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h +test_no_tx.o: /usr/include/stdint.h /usr/include/bits/wordsize.h +test_no_tx.o: /usr/include/sys/types.h /usr/include/time.h +test_no_tx.o: /usr/include/endian.h /usr/include/bits/endian.h +test_no_tx.o: /usr/include/sys/select.h /usr/include/bits/select.h +test_no_tx.o: /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h +test_no_tx.o: /usr/include/bits/socket.h /usr/include/bits/sockaddr.h +test_no_tx.o: /usr/include/asm/socket.h /usr/include/asm/sockios.h +test_no_tx.o: /usr/include/bits/in.h /usr/include/bits/byteswap.h +test_no_tx.o: ../src/mcl_lib.h diff --git a/check/flute/files/send/fdt_tsi1.xml b/check/flute/files/send/fdt_tsi1.xml new file mode 100644 index 0000000..648b0ba --- /dev/null +++ b/check/flute/files/send/fdt_tsi1.xml @@ -0,0 +1,7 @@ + + + + diff --git a/check/flute/iop/checkall.sh b/check/flute/iop/checkall.sh new file mode 100755 index 0000000..8a0ac6b --- /dev/null +++ b/check/flute/iop/checkall.sh @@ -0,0 +1,66 @@ +#!/bin/sh +# +# $Id: checkall.sh,v 1.2 2005/05/12 16:03:19 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# top validation script +# +# scans and executes all the elementary test scripts contained in this dir +# + + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./checkall.sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./checkall.sh mad_flute" + exit 1 +fi + + +test_sh_list=`ls test_*.sh` # sh scripts +test_pl_list=`ls test_*.pl` # perl scripts + + +for t in ${test_sh_list} ${test_pl_list} ; do + echo "" + echo "" + echo "------> Running test ${t}" + ./${t} $1 + val=$? + + if [ ${val} -ne 0 ] ; then + echo "" + echo "****** ERROR: Test ${t} failed! Aborting... ******" + exit + fi + echo "<------ Test ${t} passed" +done +echo "" +echo "" +echo "****** All tests succeeded! Validation OK ******" + diff --git a/check/flute/iop/test_flute_FEC.sh b/check/flute/iop/test_flute_FEC.sh new file mode 100755 index 0000000..c121dc0 --- /dev/null +++ b/check/flute/iop/test_flute_FEC.sh @@ -0,0 +1,185 @@ +#!/bin/sh +# +# $Id: test_flute_FEC.sh,v 1.2 2005/05/12 16:03:19 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + + +host_name=`uname -s` +host_network_name=`uname -n` +host_ip=`hostname -i` + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# MCL to MAD using RSE +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** MCL to MAD using RSE" +echo "" +echo "$1 -A -m:225.1.2.3 -p:9991 -v:0 -s:${host_ip} -B:./" +echo "${flute_path} ${verbosity_recv} -send -cc0 -fec2.0 -a225.1.2.3/9991 -demux1 ./" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +$1 -A -m:225.1.2.3 -p:9991 -v:0 -s:${host_ip} -B:./& +flute_recv_pid=$! + +cd ../send +../${flute_path} ${verbosity_recv} -send -cc0 -fec2.0 -a225.1.2.3/9991 -demux1 ./ & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/ + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 253 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + + + +# +# MAD to MCL using RSE +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** MAD to MCL using RSE " +echo "" +echo "${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1" +echo "$1 -S -m:225.1.2.3 -p:9991 -v:0 -x:2 -F:../" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1 & +flute_recv_pid=$! + +cd .. +$1 -S -m:225.1.2.3 -p:9991 -v:0 -x:2 -F:./send & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/${host_network_name}/send + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + diff --git a/check/flute/iop/test_flute_RLC.sh b/check/flute/iop/test_flute_RLC.sh new file mode 100755 index 0000000..b8a17fd --- /dev/null +++ b/check/flute/iop/test_flute_RLC.sh @@ -0,0 +1,185 @@ +#!/bin/sh +# +# $Id: test_flute_RLC.sh,v 1.2 2005/05/12 16:03:20 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + + +host_name=`uname -s` +host_network_name=`uname -n` +host_ip=`hostname -i` + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# MCL to MAD using RSE +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** MCL to MAD using RLC" +echo "" +echo "$1 -A -m:225.1.2.3 -p:9991 -v:0 -w:1 -c:5 -s:${host_ip} -B:./" +echo "${flute_path} ${verbosity_recv} -send -cc1 -l5 -fec1.5 -a225.1.2.3/9991 -demux1 ./" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +$1 -A -m:225.1.2.3 -p:9991 -v:0 -w:1 -c:5 -s:${host_ip} -B:./& +flute_recv_pid=$! + +cd ../send +../${flute_path} ${verbosity_recv} -send -cc1 -l5 -fec1.0 -a225.1.2.3/9991 -demux1 ./ & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/ + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 253 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + + + +# +# MAD to MCL using RSE +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** MAD to MCL using RSE " +echo "" +echo "${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1" +echo "$1 -S -m:225.1.2.3 -p:9991 -v:0 -x:2 -F:../" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_recv} -recv -cc1 -l5 -a225.1.2.3/9991 -demux1 & +flute_recv_pid=$! + +cd .. +$1 -S -m:225.1.2.3 -p:9991 -w:1 -c:5 -v:0 -F:./send & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/${host_network_name}/send + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + diff --git a/check/flute/iop/test_flute_ipv6.sh b/check/flute/iop/test_flute_ipv6.sh new file mode 100755 index 0000000..c69e6b7 --- /dev/null +++ b/check/flute/iop/test_flute_ipv6.sh @@ -0,0 +1,185 @@ +#!/bin/sh +# +# $Id: test_flute_ipv6.sh,v 1.2 2005/05/12 16:03:20 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + + +host_name=`uname -s` +host_network_name=`uname -n` +host_ip=`hostname -i` + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# MCL to MAD +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** MCL to MAD " +echo "" +echo "$1 -A -m:ff01::1 -p:9991 -v:0 -a:IP6 -B:./" +echo "${flute_path} ${verbosity_recv} -send -cc0 -fec1.0 -aff01::1/9991 -demux1 -ifneth0 ./" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +$1 -A -m:ff01::1 -p:9991 -a:IP6 -v:0 -B:./& +flute_recv_pid=$! + +cd ../send +../${flute_path} ${verbosity_recv} -send -cc0 -fec1.0 -aff01::1/9991 -demux1 -ifneth0 ./ & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/ + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 253 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + + + +# +# MAD to MCL +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** MAD to MCL " +echo "" +echo "${flute_path} ${verbosity_recv} -recv -aff01::1/9991 -ifneth0 -demux1" +echo "$1 -S -m:ff01::1 -p:9991 -v:0 -a:IP6 -F:../" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_recv} -recv -aff01::1/9991 -ifneth0 -demux1 & +flute_recv_pid=$! + +cd .. +$1 -S -m:ff01::1 -p:9991 -v:0 -a:IP6 -F:./send & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/${host_network_name}/send + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + diff --git a/check/flute/iop/test_flute_mad_to_mcl_fti_in_fdt.sh b/check/flute/iop/test_flute_mad_to_mcl_fti_in_fdt.sh new file mode 100755 index 0000000..3eb9f0a --- /dev/null +++ b/check/flute/iop/test_flute_mad_to_mcl_fti_in_fdt.sh @@ -0,0 +1,177 @@ +#!/bin/sh +# +# $Id: test_flute_mad_to_mcl_fti_in_fdt.sh,v 1.2 2005/05/12 16:03:20 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + + +host_name=`uname -s` +host_network_name=`uname -n` +host_ip=`hostname -i` + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# FTI in FDT with one big file.. +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** FTI in FDT with one big file..." +echo "" +echo "${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1" +echo "$1 -S -m:225.1.2.3 -p:9991 -v:0 -e:0 -F:../Other_Files/i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1 & +flute_recv_pid=$! + +cd ../send +$1 -S -m:225.1.2.3 -p:9991 -v:0 -e:0 -F:./Other_Files/i-am-a-BIG.file & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../../iop +#diff -r ./files/send ./files/recv +diff ../files/send/Other_Files/i-am-a-BIG.file ../files/recv/${host_network_name}/Other_Files/i-am-a-BIG.file + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + +# +# and now with several files... +# + +echo "" +echo "** FTI in FDT with several files..." +echo "" +echo "${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1" +echo "$1 -S -m:225.1.2.3 -p:9991 -v:0 -e:0 -F:../" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1 & +flute_recv_pid=$! + +cd ../ +$1 -S -m:225.1.2.3 -p:9991 -v:0 -e:0 -F:./send/ & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/${host_network_name}/send + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi diff --git a/check/flute/iop/test_flute_mad_to_mcl_half_word_headers.sh b/check/flute/iop/test_flute_mad_to_mcl_half_word_headers.sh new file mode 100755 index 0000000..27579a8 --- /dev/null +++ b/check/flute/iop/test_flute_mad_to_mcl_half_word_headers.sh @@ -0,0 +1,126 @@ +#!/bin/sh +# +# $Id: test_flute_mad_to_mcl_half_word_headers.sh,v 1.2 2005/05/12 16:03:21 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + + + +host_name=`uname -s` +host_network_name=`uname -n` +host_ip=`hostname -i` + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# half word tests +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** half word tests..." +echo "" +echo "${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1" +echo "$1 -S -m:225.1.2.3 -p:9991 -H -v:0 -F:../" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1 & +flute_recv_pid=$! + +cd .. +$1 -S -m:225.1.2.3 -p:9991 -H -v:0 -F:./send & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/${host_network_name}/send + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi diff --git a/check/flute/iop/test_flute_mad_to_mcl_multiple_files.sh b/check/flute/iop/test_flute_mad_to_mcl_multiple_files.sh new file mode 100755 index 0000000..b78911b --- /dev/null +++ b/check/flute/iop/test_flute_mad_to_mcl_multiple_files.sh @@ -0,0 +1,186 @@ +#!/bin/sh +# +# $Id: test_flute_mad_to_mcl_multiple_files.sh,v 1.2 2005/05/12 16:03:21 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + + +host_name=`uname -s` +host_network_name=`uname -n` +host_ip=`hostname -i` + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# multicast tests first +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** Multicast tests..." +echo "" +echo "${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1" +echo "$1 -S -m:225.1.2.3 -p:9991 -v:0 -F:../" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1 & +flute_recv_pid=$! + +cd .. +$1 -S -m:225.1.2.3 -p:9991 -v:0 -F:./send & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/${host_network_name}/send + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + +# +# and now unicast tests... +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** And unicast tests now..." +echo "" +echo "${flute_path} ${verbosity_send} -recv -a127.0.0.1/9998 -demux1" +echo "$1 -S -m:127.0.0.1 -p:9998 -v:0 -F:./" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_send} -recv -a127.0.0.1/9998 -demux1 & +flute_recv_pid=$! + +cd .. +$1 -S -m:127.0.0.1 -p:9998 -v:0 -F:./ & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/${host_network_name}/send + +diff_val=$? + + +# do not test send_val return value here as in unicast, +# the sender is always stopped as soon as the receiver leaves +# with a sendmsg error. This is normal so ignore it and only +# rely on diff tests +# +if [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + exit 0 +fi diff --git a/check/flute/iop/test_flute_mad_to_mcl_xfert.sh b/check/flute/iop/test_flute_mad_to_mcl_xfert.sh new file mode 100755 index 0000000..40c6ed2 --- /dev/null +++ b/check/flute/iop/test_flute_mad_to_mcl_xfert.sh @@ -0,0 +1,186 @@ +#!/bin/sh +# +# $Id: test_flute_mad_to_mcl_xfert.sh,v 1.2 2005/05/12 16:03:21 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + + +host_name=`uname -s` +host_network_name=`uname -n` +host_ip=`hostname -i` + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# multicast tests first +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** Multicast tests..." +echo "" +echo "${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1" +echo "$1 -S -m:225.1.2.3 -p:9991 -v:0 -F:../Other_Files/i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -demux1 & +flute_recv_pid=$! + +cd ../send +$1 -S -m:225.1.2.3 -p:9991 -v:0 -F:./Other_Files/i-am-a-BIG.file & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../../iop +#diff -r ./files/send ./files/recv +diff ../files/send/Other_Files/i-am-a-BIG.file ../files/recv/${host_network_name}/Other_Files/i-am-a-BIG.file + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + +# +# and now unicast tests... +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** And unicast tests now..." +echo "" +echo "${flute_path} ${verbosity_send} -recv -a127.0.0.1/9998 -demux1" +echo "$1 -S -m:127.0.0.1 -p:9998 -v:0 -F:./Other_Files/i-am-a-BIG.file/" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +../${flute_path} ${verbosity_send} -recv -a127.0.0.1/9998 -demux1 & +flute_recv_pid=$! + +cd ../send +$1 -S -m:127.0.0.1 -p:9998 -v:0 -F:./Other_Files/i-am-a-BIG.file & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../../iop +#diff -r ./files/send ./files/recv +diff ../files/send/Other_Files/i-am-a-BIG.file ../files/recv/${host_network_name}/Other_Files/i-am-a-BIG.file + +diff_val=$? + + +# do not test send_val return value here as in unicast, +# the sender is always stopped as soon as the receiver leaves +# with a sendmsg error. This is normal so ignore it and only +# rely on diff tests +# +if [ ${recv_val} -ne 0 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + exit 0 +fi diff --git a/check/flute/iop/test_flute_mcl_to_mad_multiple_files.sh b/check/flute/iop/test_flute_mcl_to_mad_multiple_files.sh new file mode 100755 index 0000000..5e7bbca --- /dev/null +++ b/check/flute/iop/test_flute_mcl_to_mad_multiple_files.sh @@ -0,0 +1,125 @@ +#!/bin/sh +# +# $Id: test_flute_mcl_to_mad_multiple_files.sh,v 1.2 2005/05/12 16:03:22 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + + +host_name=`uname -s` +host_network_name=`uname -n` +host_ip=`hostname -i` + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# multicast tests +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** Multicast tests..." +echo "" +echo "$1 -A -m:225.1.2.3 -p:9991 -v:0 -B:./ -s:${host_ip}" +echo "${flute_path} ${verbosity_recv} -send -cc0 -fec1.0 -a225.1.2.3/9991 -demux1 ./send" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +$1 -A -m:225.1.2.3 -p:9991 -v:0 -B:./ -s:${host_ip} & +flute_recv_pid=$! + +cd ../send +../${flute_path} ${verbosity_recv} -send -cc0 -fec1.0 -a225.1.2.3/9991 -demux1 ./ & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../../iop +#diff -r ./files/send ./files/recv +diff ../files/send/ ../files/recv/ + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 253 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + diff --git a/check/flute/iop/test_flute_mcl_to_mad_xfert.sh b/check/flute/iop/test_flute_mcl_to_mad_xfert.sh new file mode 100755 index 0000000..0801d86 --- /dev/null +++ b/check/flute/iop/test_flute_mcl_to_mad_xfert.sh @@ -0,0 +1,186 @@ +#!/bin/sh +# +# $Id: test_flute_mcl_to_mad_xfert.sh,v 1.2 2005/05/12 16:03:22 moi Exp $ +# +# Copyright (c) 1999-2004 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +#echo "WARNING: test skipped !!!!!!" +#exit 0 + +if [ -z $1 ] +then + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + +if [ ! -x $1 ] +then + echo "You specified a non executable file." + echo "You must specify the flute binary file of MADs Flute implementation." + echo "Syntax: ./test_.._...sh mad_flute" + exit 1 +fi + + +host_name=`uname -s` +host_network_name=`uname -n` +host_ip=`hostname -i` + +case ${host_name} in + + Linux) + echo "Running FLUTE Linux Send/Recv Test" + flute_path="../../../bin/linux/flute" + ;; + + SunOS) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/solaris/flute" + ;; + + FreeBSD) + echo "Running FLUTE Solaris Send/Recv Test" + flute_path="../../../bin/freebsd/flute" + ;; + + # other OS???? todo +esac + +# +# multicast tests first +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** Multicast tests..." +echo "" +echo "$1 -A -m:225.1.2.3 -p:9991 -v:0 -s:${host_ip} -B:./" +echo "${flute_path} ${verbosity_send} -send -cc0 -fec1.0 -a225.1.2.3/9991 -phigh -demux1 ../Other_Files/i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +$1 -A -m:225.1.2.3 -p:9991 -v:0 -s:${host_ip} -B:./& +flute_recv_pid=$! + +cd ../send +../${flute_path} ${verbosity_send} -send -cc0 -fec1.0 -a225.1.2.3/9991 -demux1 -phigh ./Other_Files/i-am-a-BIG.file & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if sender has finished before receiver ?? + +cd ../../iop +#diff -r ./files/send ./files/recv +diff ../files/send/Other_Files/i-am-a-BIG.file ../files/recv/Other_Files/i-am-a-BIG.file + +diff_val=$? + +if [ ${send_val} -ne 0 ] +then + echo "FLUTE Send Failed" + exit 1 + +elif [ ${recv_val} -ne 253 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + +# +# and now unicast tests... +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='-stat1' # has to be at least -v1 or stat1 +#verbosity_send='-v5' # sender part +verbosity_send='-stat1' # has to be at least -v1 or stat1 + +echo "" +echo "** And unicast tests now..." +echo "" +echo "$1 -A -U -m:127.0.0.1 -p:9998 -v:0 -s:127.0.0.1 -B:./" +echo "${flute_path} ${verbosity_send} -send -cc0 -fec1.0 -a127.0.0.1/9998 -demux1 -phigh ./Other_Files/i-am-a-BIG.file" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ../files/recv/* +cd ../files/recv +$1 -A -U -m:127.0.0.1 -p:9998 -v:0 -s:127.0.0.1 -B:./ & +flute_recv_pid=$! + +cd ../send +../${flute_path} ${verbosity_send} -send -cc0 -fec1.0 -a127.0.0.1/9998 -demux1 -phigh ./Other_Files/i-am-a-BIG.file & +flute_send_pid=$! + +wait ${flute_recv_pid} +recv_val=$? + +wait ${flute_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../../iop +#diff -r ./files/send ./files/recv +diff ../files/send/Other_Files/i-am-a-BIG.file ../files/recv/Other_Files/i-am-a-BIG.file + +diff_val=$? + + +# do not test send_val return value here as in unicast, +# the sender is always stopped as soon as the receiver leaves +# with a sendmsg error. This is normal so ignore it and only +# rely on diff tests +# +if [ ${recv_val} -ne 253 ] +then + echo "FLUTE Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + exit 0 +fi diff --git a/check/flute/test_open_close b/check/flute/test_open_close new file mode 100755 index 0000000..1b66acb Binary files /dev/null and b/check/flute/test_open_close differ diff --git a/check/flute/test_open_close.cpp b/check/flute/test_open_close.cpp new file mode 100644 index 0000000..7067706 --- /dev/null +++ b/check/flute/test_open_close.cpp @@ -0,0 +1,51 @@ +/* $Id: test_open_close.cpp,v 1.2 2005/05/12 16:03:17 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * test_open_close.c + * + * open and closes a flute session. + */ + +#include "../../src/flute_lib/FluteAPI.h" + + +/* the flute session class */ +class Flute *myflute = NULL; +class FluteSender *myflutesender = NULL; +class FluteReceiver *myflutereceiver = NULL; + + +int main (int argc, char *argv[]) +{ + + myflute = new Flute(); + myflutesender = new FluteSender(); + myflutereceiver = new FluteReceiver(); + + + delete myflute; + delete myflutesender; + delete myflutereceiver; + +} diff --git a/check/norm/Makefile b/check/norm/Makefile new file mode 100644 index 0000000..50c281b --- /dev/null +++ b/check/norm/Makefile @@ -0,0 +1,111 @@ +# $Id: Makefile,v 1.17 2004/12/10 10:37:13 chneuman Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Makefile.common as appropriate +include ../../Makefile.common + + +# libraries required +ifeq (${OS},linux) + # Linux version + # MCL library requires -lpthread + # add MPATROL support if required + # + BINDIR = ../../bin/linux + LIBRARIES = -lc -lm -lpthread ${BINDIR}/libmclnorm.a +endif + +ifeq (${OS},solaris) + # Solaris version: requires -lsocket -lnsl and -L/usr/ucblib -lucb + # + BINDIR = ../../bin/solaris + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -lpthread ${BINDIR}/libmclnorm.a +endif + +ifeq (${OS},freebsd) + # FreeBSD version + BINDIR = ../../bin/freebsd + LDPC_BINDIR = ../../../ldpc/bin/freebsd + LIBRARIES = -lc -lm -pthread ${BINDIR}/libmclnorm.a +endif + + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +CFLAGS = -O -g ${OSFLAGS} -DNORM + + +# add purify linker for memory debug (Solaris only). +# Purify 4.0 Solaris 2, Copyright (C) 1992-1996 Pure Software Inc. +# +#CCLINK_PURE = purify $(CC) +CCLINK_PURE = purify -cache-dir=/tmp $(CC) + + +# List of source and object test files +SRCFILES = test_tx.c test_multi_sessions1.c test_multi_sessions2.c +OFILES = ${SRCFILES:.c=.o} +TARGETS = ${SRCFILES:.c=} + + + +###### Dependancies ###### + +all: ${TARGETS} + +test_tx: test_tx.o ${BINDIR}/libmclnorm.a + ${CC} ${CFLAGS} test_tx.o ${LIBRARIES} -o test_tx + #strip test_tx + +test_multi_sessions1: test_multi_sessions1.o ${BINDIR}/libmclnorm.a + ${CC} ${CFLAGS} test_multi_sessions1.o ${LIBRARIES} -o test_multi_sessions1 + #strip test_multi_sessions1 + +test_multi_sessions2: test_multi_sessions2.o ${BINDIR}/libmclnorm.a + ${CC} ${CFLAGS} test_multi_sessions2.o ${LIBRARIES} -o test_multi_sessions2 + #strip test_multi_sessions2 + +pure: test_tx.o ${BINDIR}/libmclnorm.a + ${CCLINK_PURE} ${CFLAGS} test_tx.o ${LIBRARIES} -o test_tx + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in core ${TARGETS} ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +test_tx.o: ../../src/common/mcl_lib_api.h ../../src/common/mcl_types.h +test_tx.o: ../../src/norm/mcl_lib_api_norm.h +test_multi_sessions1.o: ../../src/common/mcl_lib_api.h +test_multi_sessions1.o: ../../src/common/mcl_types.h +test_multi_sessions1.o: ../../src/norm/mcl_lib_api_norm.h +test_multi_sessions2.o: ../../src/common/mcl_lib_api.h +test_multi_sessions2.o: ../../src/common/mcl_types.h +test_multi_sessions2.o: ../../src/norm/mcl_lib_api_norm.h diff --git a/check/norm/checkall.sh b/check/norm/checkall.sh new file mode 100755 index 0000000..9936e0c --- /dev/null +++ b/check/norm/checkall.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# +# $Id: checkall.sh,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ +# +# Copyright (c) 1999-2003 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + +# top validation script +# +# scans and executes all the elementary test scripts contained in this dir +# + +test_sh_list=`ls test_*.sh` # sh scripts +test_pl_list=`ls test_*.pl` # perl scripts + + +for t in ${test_sh_list} ${test_pl_list} ; do + echo "" + echo "" + echo "------> Running test ${t}" + ./${t} + val=$? + + if [ ${val} -ne 0 ] ; then + echo "" + echo "****** ERROR: Test ${t} failed! Aborting... ******" + exit + fi + echo "<------ Test ${t} passed" +done +echo "" +echo "" +echo "****** All tests succeeded! Validation OK ******" + diff --git a/check/norm/fcast_test/recv/0_Byte_File b/check/norm/fcast_test/recv/0_Byte_File new file mode 100755 index 0000000..e69de29 diff --git a/check/norm/fcast_test/recv/2_Bytes_File b/check/norm/fcast_test/recv/2_Bytes_File new file mode 100755 index 0000000..0cfbf08 --- /dev/null +++ b/check/norm/fcast_test/recv/2_Bytes_File @@ -0,0 +1 @@ +2 diff --git a/check/norm/fcast_test/recv/3_Bytes_File b/check/norm/fcast_test/recv/3_Bytes_File new file mode 100755 index 0000000..ff3eb13 --- /dev/null +++ b/check/norm/fcast_test/recv/3_Bytes_File @@ -0,0 +1 @@ +3! diff --git a/check/norm/fcast_test/recv/Other_Files/i-am-a-BIG.file b/check/norm/fcast_test/recv/Other_Files/i-am-a-BIG.file new file mode 100755 index 0000000..fb63f03 --- /dev/null +++ b/check/norm/fcast_test/recv/Other_Files/i-am-a-BIG.file @@ -0,0 +1 @@ +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" \ No newline at end of file diff --git a/check/norm/fcast_test/recv/Other_Files/i-am-a.file b/check/norm/fcast_test/recv/Other_Files/i-am-a.file new file mode 100755 index 0000000..753cf7a --- /dev/null +++ b/check/norm/fcast_test/recv/Other_Files/i-am-a.file @@ -0,0 +1,95 @@ +# $Id: i-am-a.file,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Rules.mk + + +# libraries required +ifeq (${OS},linux) + # Linux version + # MCL library requires -lpthread + # + BINDIR = ../bin/linux + LIBRARIES = -lc -lm -lpthread ${BINDIR}/libmcl.a +endif + +ifeq (${OS},solaris) + # Solaris version: requires -lsocket -lnsl and -L/usr/ucblib -lucb + # + BINDIR = ../bin/solaris + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -lpthread ${BINDIR}/libmcl.a +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +CFLAGS = -O -g ${OSFLAGS} + +# cc version +# -fullwarn for IRIX c compiler +#CFLAGS = -O -fullwarn ${OSFLAGS} + +SRCFILES = test_no_tx.c +OFILES = test_no_tx.o +TARGETS = test_no_tx + + +###### Dependancies ###### + +all: ${TARGETS} + +test_no_tx: test_no_tx.o ${BINDIR}/libmcl.a + ${CC} ${CFLAGS} test_no_tx.o ${LIBRARIES} -o test_no_tx + strip test_no_tx + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in core ${TARGETS} ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # use -p to say that objects are in the bin dir + # ${DEPEND} -pbin/ -- ${CFLAGS} -- ${SRCFILES} + ${DEPEND} -- ${CFLAGS} -- ${SRCFILES} + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +test_no_tx.o: /usr/include/stdio.h /usr/include/features.h +test_no_tx.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +test_no_tx.o: /usr/include/bits/types.h /usr/include/libio.h +test_no_tx.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +test_no_tx.o: /usr/include/netinet/in.h /usr/include/limits.h +test_no_tx.o: /usr/include/bits/posix1_lim.h /usr/include/bits/local_lim.h +test_no_tx.o: /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h +test_no_tx.o: /usr/include/stdint.h /usr/include/bits/wordsize.h +test_no_tx.o: /usr/include/sys/types.h /usr/include/time.h +test_no_tx.o: /usr/include/endian.h /usr/include/bits/endian.h +test_no_tx.o: /usr/include/sys/select.h /usr/include/bits/select.h +test_no_tx.o: /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h +test_no_tx.o: /usr/include/bits/socket.h /usr/include/bits/sockaddr.h +test_no_tx.o: /usr/include/asm/socket.h /usr/include/asm/sockios.h +test_no_tx.o: /usr/include/bits/in.h /usr/include/bits/byteswap.h +test_no_tx.o: ../src/mcl_lib.h diff --git a/check/norm/fcast_test/send/0_Byte_File b/check/norm/fcast_test/send/0_Byte_File new file mode 100644 index 0000000..e69de29 diff --git a/check/norm/fcast_test/send/2_Bytes_File b/check/norm/fcast_test/send/2_Bytes_File new file mode 100644 index 0000000..0cfbf08 --- /dev/null +++ b/check/norm/fcast_test/send/2_Bytes_File @@ -0,0 +1 @@ +2 diff --git a/check/norm/fcast_test/send/3_Bytes_File b/check/norm/fcast_test/send/3_Bytes_File new file mode 100644 index 0000000..ff3eb13 --- /dev/null +++ b/check/norm/fcast_test/send/3_Bytes_File @@ -0,0 +1 @@ +3! diff --git a/check/norm/fcast_test/send/Other_Files/i-am-a-BIG.file b/check/norm/fcast_test/send/Other_Files/i-am-a-BIG.file new file mode 100644 index 0000000..fb63f03 --- /dev/null +++ b/check/norm/fcast_test/send/Other_Files/i-am-a-BIG.file @@ -0,0 +1 @@ +"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" \ No newline at end of file diff --git a/check/norm/fcast_test/send/Other_Files/i-am-a.file b/check/norm/fcast_test/send/Other_Files/i-am-a.file new file mode 100644 index 0000000..753cf7a --- /dev/null +++ b/check/norm/fcast_test/send/Other_Files/i-am-a.file @@ -0,0 +1,95 @@ +# $Id: i-am-a.file,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Rules.mk + + +# libraries required +ifeq (${OS},linux) + # Linux version + # MCL library requires -lpthread + # + BINDIR = ../bin/linux + LIBRARIES = -lc -lm -lpthread ${BINDIR}/libmcl.a +endif + +ifeq (${OS},solaris) + # Solaris version: requires -lsocket -lnsl and -L/usr/ucblib -lucb + # + BINDIR = ../bin/solaris + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -lpthread ${BINDIR}/libmcl.a +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +CFLAGS = -O -g ${OSFLAGS} + +# cc version +# -fullwarn for IRIX c compiler +#CFLAGS = -O -fullwarn ${OSFLAGS} + +SRCFILES = test_no_tx.c +OFILES = test_no_tx.o +TARGETS = test_no_tx + + +###### Dependancies ###### + +all: ${TARGETS} + +test_no_tx: test_no_tx.o ${BINDIR}/libmcl.a + ${CC} ${CFLAGS} test_no_tx.o ${LIBRARIES} -o test_no_tx + strip test_no_tx + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in core ${TARGETS} ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # use -p to say that objects are in the bin dir + # ${DEPEND} -pbin/ -- ${CFLAGS} -- ${SRCFILES} + ${DEPEND} -- ${CFLAGS} -- ${SRCFILES} + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +test_no_tx.o: /usr/include/stdio.h /usr/include/features.h +test_no_tx.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stddef.h +test_no_tx.o: /usr/lib/gcc-lib/i386-redhat-linux/egcs-2.91.66/include/stdarg.h +test_no_tx.o: /usr/include/bits/types.h /usr/include/libio.h +test_no_tx.o: /usr/include/_G_config.h /usr/include/bits/stdio_lim.h +test_no_tx.o: /usr/include/netinet/in.h /usr/include/limits.h +test_no_tx.o: /usr/include/bits/posix1_lim.h /usr/include/bits/local_lim.h +test_no_tx.o: /usr/include/linux/limits.h /usr/include/bits/posix2_lim.h +test_no_tx.o: /usr/include/stdint.h /usr/include/bits/wordsize.h +test_no_tx.o: /usr/include/sys/types.h /usr/include/time.h +test_no_tx.o: /usr/include/endian.h /usr/include/bits/endian.h +test_no_tx.o: /usr/include/sys/select.h /usr/include/bits/select.h +test_no_tx.o: /usr/include/bits/sigset.h /usr/include/sys/sysmacros.h +test_no_tx.o: /usr/include/bits/socket.h /usr/include/bits/sockaddr.h +test_no_tx.o: /usr/include/asm/socket.h /usr/include/asm/sockios.h +test_no_tx.o: /usr/include/bits/in.h /usr/include/bits/byteswap.h +test_no_tx.o: ../src/mcl_lib.h diff --git a/check/norm/test_fcast_mcl_modes.sh b/check/norm/test_fcast_mcl_modes.sh new file mode 100755 index 0000000..02ccf9e --- /dev/null +++ b/check/norm/test_fcast_mcl_modes.sh @@ -0,0 +1,108 @@ +#!/bin/sh +# +# $Id: test_fcast_mcl_modes.sh,v 1.3 2004/09/22 14:10:20 chneuman Exp $ +# +# Copyright (c) 2003 INRIA - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# +# fcast validation script #3 : Fcast options and MCL Modes Tests +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux non recursive send/recv test" + fcast_path="../../bin/linux/fcastn" + ;; + + SunOS) + echo "Running FCAST Solaris non recursive send/recv test" + fcast_path="../../bin/solaris/fcastn" + ;; + + FreeBSD) + echo "Running FCAST FreeBSD non recursive send/recv test" + fcast_path="../../bin/freebsd/fcastn" + ;; + + # other OS???? todo +esac + +# for debug... +#verbosity_recv='-v6' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +# file sent +file='./Other_Files/i-am-a-BIG.file' + + +echo "" +echo "** Multicast tests only..." +echo "" + +echo "--- Basic Test..." +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -never -a225.1.2.3/9991 & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 ${file} & +fcast_send_pid=$! + + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + + +cd ../.. +diff ./fcast_test/send/${file} ./fcast_test/recv/${file} +diff_val=$? + +if [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + echo "-- Test OK!" +fi + + diff --git a/check/norm/test_fcast_non_recursive.sh b/check/norm/test_fcast_non_recursive.sh new file mode 100755 index 0000000..cbddc98 --- /dev/null +++ b/check/norm/test_fcast_non_recursive.sh @@ -0,0 +1,156 @@ +#!/bin/sh +# +# $Id: test_fcast_non_recursive.sh,v 1.2 2004/09/22 14:10:20 chneuman Exp $ +# +# Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# +# fcast validation script #2 : non recursive Send/Recv Test +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux non recursive send/recv test" + fcast_path="../../bin/linux/fcastn" + ;; + + SunOS) + echo "Running FCAST Solaris non recursive send/recv test" + fcast_path="../../bin/solaris/fcastn" + ;; + + FreeBSD) + echo "Running FCAST FreeBSD non recursive send/recv test" + fcast_path="../../bin/freebsd/fcastn" + ;; + + # other OS???? todo +esac + +# for debug... +#verbosity_recv='-v1' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +# file sent +file='./Other_Files/i-am-a-BIG.file' + + +# +# multicast tests first +# +echo "" +echo "** Multicast tests..." +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -never -a225.3.4.5/9998 & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -a225.3.4.5/9998 ${file} & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +diff ./fcast_test/send/${file} ./fcast_test/recv/${file} +diff_val=$? + + +if [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + + +# +# and unicast tests... +# +echo "" +echo "** And unicast tests now..." +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -never -a127.0.0.1/9998 & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -a127.0.0.1/9998 ${file} & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +diff ./fcast_test/send/${file} ./fcast_test/recv/${file} +diff_val=$? + + +# do not test send_val return value here as in unicast, +# the sender is always stopped as soon as the receiver leaves +# with a sendmsg error. This is normal so ignore it and only +# rely on diff tests +# +if [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + exit 0 +fi diff --git a/check/norm/test_fcast_unicast_xfert.sh b/check/norm/test_fcast_unicast_xfert.sh new file mode 100755 index 0000000..eea1082 --- /dev/null +++ b/check/norm/test_fcast_unicast_xfert.sh @@ -0,0 +1,111 @@ +#!/bin/sh +# +# $Id: test_fcast_unicast_xfert.sh,v 1.3 2004/09/22 14:10:20 chneuman Exp $ +# +# Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# +# fcast validation script #1 : Send/Recv Test +# unicast tests +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux non recursive send/recv test" + fcast_path="../../bin/linux/fcastn" + ;; + + SunOS) + echo "Running FCAST Solaris non recursive send/recv test" + fcast_path="../../bin/solaris/fcastn" + ;; + + FreeBSD) + echo "Running FCAST FreeBSD non recursive send/recv test" + fcast_path="../../bin/freebsd/fcastn" + ;; + + # other OS???? todo +esac + + +# +# unicast tests... +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +echo "" +echo "** unicast tests..." +echo "" +echo "${fcast_path} ${verbosity_recv} -recv -a127.0.0.1/9998 -never" +echo "${fcast_path} ${verbosity_send} -send -a127.0.0.1/9998 -R ./" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -a127.0.0.1/9998 -never & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -a127.0.0.1/9998 -R ./ & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +diff -r ./fcast_test/send ./fcast_test/recv +diff_val=$? + + +# do not test send_val return value here as in unicast, +# the sender is always stopped as soon as the receiver leaves +# with a sendmsg error. This is normal so ignore it and only +# rely on diff tests +# +if [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 + +else + exit 0 +fi + diff --git a/check/norm/test_fcast_xfert.sh b/check/norm/test_fcast_xfert.sh new file mode 100755 index 0000000..fc11ba8 --- /dev/null +++ b/check/norm/test_fcast_xfert.sh @@ -0,0 +1,112 @@ +#!/bin/sh +# +# $Id: test_fcast_xfert.sh,v 1.3 2004/09/22 14:10:21 chneuman Exp $ +# +# Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +# (main authors: Julien Laboure - julien.laboure@inrialpes.fr +# Vincent Roca - vincent.roca@inrialpes.fr +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# skipped ! +# echo "WARNING: test skipped !!!!!!" +# exit 0 + +# +# fcast validation script #1 : Send/Recv Test +# multicast tests +# +# +host_name=`uname -s` + + +case ${host_name} in + + Linux) + echo "Running FCAST Linux non recursive send/recv test" + fcast_path="../../bin/linux/fcastn" + ;; + + SunOS) + echo "Running FCAST Solaris non recursive send/recv test" + fcast_path="../../bin/solaris/fcastn" + ;; + + FreeBSD) + echo "Running FCAST FreeBSD non recursive send/recv test" + fcast_path="../../bin/freebsd/fcastn" + ;; + + # other OS???? todo +esac + +# +# multicast tests +# + +# for debug... +#verbosity_recv='-v5' # receiver part +verbosity_recv='' +#verbosity_send='-v5' # sender part +verbosity_send='' + +echo "" +echo "** Multicast tests..." +echo "" +echo "${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never " +echo "${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -R ./" +echo "" + +recv_val=1 +send_val=1 +rm -Rf ./fcast_test/recv/* +cd fcast_test/recv +../../${fcast_path} ${verbosity_recv} -recv -a225.1.2.3/9991 -never & +fcast_recv_pid=$! + +cd ../send +../../${fcast_path} ${verbosity_send} -send -a225.1.2.3/9991 -R ./ & +fcast_send_pid=$! + +wait ${fcast_recv_pid} +recv_val=$? + +wait ${fcast_send_pid} +send_val=$? +# TODO : what if Sender has finished before receiver ?? + +cd ../.. +diff -r ./fcast_test/send ./fcast_test/recv +diff_val=$? + + +if [ ${send_val} -ne 0 ] +then + echo "FCAST Send Failed" + exit 1 + +elif [ ${recv_val} -ne 0 ] +then + echo "FCAST Recv Failed" + exit 1 + +elif [ ${diff_val} -ne 0 ] +then + echo "Test failed: received files do not match sent files!" + exit 1 +fi + diff --git a/check/norm/test_multi_sessions.sh b/check/norm/test_multi_sessions.sh new file mode 100755 index 0000000..939d573 --- /dev/null +++ b/check/norm/test_multi_sessions.sh @@ -0,0 +1,47 @@ +#!/bin/sh +# +# $Id: test_multi_sessions.sh,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ +# +# Copyright (c) 2003 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test the MCL with a multi-session application + +#./test_multi_sessions1 & +#pid=$! +#wait ${pid} +#val=$? + +./test_multi_sessions1 +val=$? + +echo "returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +fi + +./test_multi_sessions2 +val=$? + +echo "returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +fi + +exit 0 diff --git a/check/norm/test_multi_sessions1.c b/check/norm/test_multi_sessions1.c new file mode 100644 index 0000000..d757065 --- /dev/null +++ b/check/norm/test_multi_sessions1.c @@ -0,0 +1,112 @@ +/* $Id: test_multi_sessions1.c,v 1.3 2004/09/22 14:10:21 chneuman Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_multi_sessions1.c + */ + +#include +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#ifdef SOLARIS /* with solaris the max # of opened fd is much lower! */ +#define SESSION_NB 5 /* number of sessions */ +#else +//#define SESSION_NB 10 /* number of sessions */ +#define SESSION_NB 2 /* number of sessions */ +#endif +#define BUFLEN 2400 /* buffer size */ +#define VERBOSITY 5 /* verbosity level */ + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("230.0.0.0")); /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int i; + int verbose = VERBOSITY; + + printf("test_multi_sessions1: create %d sending sessions...\n", SESSION_NB); + for (i = 0; i < BUFLEN; i++) + buf[i] = (char)i; + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose >= 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + port += 10; /* incr port and addr */ + addr += 10; + } + printf("\ntest_multi_sessions1: write on the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_send(id[ses], buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_multi_sessions1: close the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_multi_sesions1 ok\n"); + return 0; +} + diff --git a/check/norm/test_multi_sessions2.c b/check/norm/test_multi_sessions2.c new file mode 100644 index 0000000..55da506 --- /dev/null +++ b/check/norm/test_multi_sessions2.c @@ -0,0 +1,108 @@ +/* $Id: test_multi_sessions2.c,v 1.2 2004/09/22 14:10:21 chneuman Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_multi_sessions2.c + * for the receiver side, no read... + */ + +#include +#ifdef FREEBSD +#include +#endif + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../../src/common/mcl_lib_api.h" + +#ifdef SOLARIS /* with solaris the max # of opened fd is much lower! */ +#define SESSION_NB 5 /* number of sessions */ +#else +#define SESSION_NB 10 /* number of sessions */ +#endif +#define VERBOSITY 0 /* verbosity level */ + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int port = 2000; /* in host format! */ + unsigned long addr = ntohl(inet_addr("230.0.0.0")); /* in host format! */ + int err; + int ses; + int verbose = VERBOSITY; + + printf("test_multi_sessions2: create %d receiving sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("r")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + if (verbose >= 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + port += 20; /* incr port and addr */ + addr += 20; + } + printf("\ntest_multi_sessions2: finish init of the %d sessions with null recv...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_recv(id[ses], NULL, 0)) < 0) { + printf("ERROR: mcl_recv failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_multi_sessions2: close the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_multi_sesions2 ok\n"); + return 0; +} + diff --git a/check/norm/test_tx.c b/check/norm/test_tx.c new file mode 100644 index 0000000..7923685 --- /dev/null +++ b/check/norm/test_tx.c @@ -0,0 +1,133 @@ +/* $Id: test_tx.c,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * test_tx.c + */ + +#include +#include + +#ifdef WIN32 +#include +#else +#include +#include +#include +#endif /* OS_DEP */ + +#include /* for exit */ +#include /* for memset */ +#include "../../src/common/mcl_lib_api.h" + +#define SESSION_NB 2 /* number of sessions */ +#define BUFLEN 150000 /* buffer size in bytes */ +#define VERBOSITY 0 /* verbosity level */ +#define STATS 1 /* statistics level */ +#define SEND_NB 10 /* number of calls to mcl_send() */ + +int +main (int argc, + char *argv[]) +{ + int id[SESSION_NB]; + int port[SESSION_NB] = {2000, 2100}; /* in host format! */ + unsigned long addr[SESSION_NB] = { + ntohl(inet_addr("225.1.0.0")), + ntohl(inet_addr("225.2.0.0"))}; /* in host format! */ + int err; + int ses; + char buf[BUFLEN]; + int verbose = VERBOSITY; + int stats = STATS; + int ttl = 2; + //int set = 1; /* set value for mcl_ctl */ + int send_nb; /* number of call to mcl_send */ + + printf("test_tx: create %d sending sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((id[ses] = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed for session %d\n", ses); + exit(-1); + } + if (verbose > 0) { + err = mcl_ctl(id[ses], MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + if (err != 0) { + printf("ERROR: mcl_ctl VERBOSITY failed for session %d\n", ses); + exit(-1); + } + } + if (stats > 0) { + err = mcl_ctl(id[ses], MCL_OPT_STATS, (void*)&stats, sizeof(stats)); + if (err != 0) { + printf("ERROR: mcl_ctl STATS failed for session %d\n", ses); + exit(-1); + } + } + err = mcl_ctl(id[ses], MCL_OPT_PORT, (void*)&port[ses], sizeof(*port)); + if (err != 0) { + printf("ERROR: mcl_ctl PORT failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_ADDR, (void*)&addr[ses], sizeof(*addr)); + if (err != 0) { + printf("ERROR: mcl_ctl ADDR failed for session %d\n", ses); + exit(-1); + } + err = mcl_ctl(id[ses], MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + if (err != 0) { + printf("ERROR: mcl_ctl TTL failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_tx: finish the init of the %d sessions...\n", + SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_send(id[ses], NULL, 0)) < 0) { + printf("ERROR: mcl_send(NULL,0) failed for session %d\n", ses); + exit(-1); + } + } + printf("\ntest_tx: write on the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + memset(buf, ses, BUFLEN); /* init buffer with session # */ + for (send_nb = SEND_NB; send_nb > 0; send_nb--) { + if ((err = mcl_send(id[ses], buf, BUFLEN)) < 0) { + printf("ERROR: mcl_send failed for session %d\n", ses); + exit(-1); + } + } + } + printf("\ntest_tx: close the %d sessions...\n", SESSION_NB); + for (ses = 0; ses < SESSION_NB; ses++) { + printf(" %d ", ses); + if ((err = mcl_close(id[ses])) < 0) { + printf("ERROR: mcl_close failed for session %d\n", ses); + exit(-1); + } + } + printf("\n... test_tx ok\n"); + return 0; +} + diff --git a/check/norm/test_tx.sh b/check/norm/test_tx.sh new file mode 100755 index 0000000..29fa897 --- /dev/null +++ b/check/norm/test_tx.sh @@ -0,0 +1,36 @@ +#!/bin/sh +# +# $Id: test_tx.sh,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ +# +# Copyright (c) 2003 INRIA - All rights reserved +# (main author: Vincent Roca - vincent.roca@inrialpes.fr) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +# USA. + + +# test the MCL with an application that only performs +# mcl_open and immediately mcl_close + +./test_tx +val=$? + +echo "${pid} returns ${val}" +if [ ${val} -ne 0 ] ; then + exit 1 +else + exit 0 +fi + diff --git a/doc/.how_to_do_a_release.txt.swo b/doc/.how_to_do_a_release.txt.swo new file mode 100644 index 0000000..a3b16e3 Binary files /dev/null and b/doc/.how_to_do_a_release.txt.swo differ diff --git a/doc/.how_to_do_a_release.txt.swp b/doc/.how_to_do_a_release.txt.swp new file mode 100644 index 0000000..8e80431 Binary files /dev/null and b/doc/.how_to_do_a_release.txt.swp differ diff --git a/doc/FAQ.txt b/doc/FAQ.txt new file mode 100644 index 0000000..697db71 --- /dev/null +++ b/doc/FAQ.txt @@ -0,0 +1,498 @@ + $Id: FAQ.txt,v 1.9 2005/03/22 16:22:17 francill Exp $ + -------------------------------------------------------------- + MCLv3, FCAST/FCASTN and FLUTE Frequently Asked Questions (FAQ) + vincent.roca@inrialpes.fr + -------------------------------------------------------------- + + +1- General + 1.1- What is MCL useful for ? + 1.2- What are the differences between the "on-demand" (-cont arg of FCAST) + and "push" (default) modes ? + 1.3- How can I be sure that receivers actually finished receiving the file ? + 1.4- I have a problem not listed, who can help me ? + 1.5- I already have an application and want to use MCL for the multicast + distribution. Is it possible ? + 1.6- Is MCL's FCAST the same as Jim Gemmel's FCAST (MS) ? + 1.7- Is MCL compliant with the ALC/LCT documents and FLUTE ? + +2- Performances + 2.1- What are the maximum FCAST performances ? + 2.2- FCAST does not send packets immediately. It is normal ? + 2.3- The disk activity is very high at the sending FCAST. Is it normal ? + 2.4- The disk activity is very high at the receiving FCAST. Is it normal ? + 2.5- How can I improve the FCAST performances ? + 2.6- Why is the standard FTP X times faster than FCAST ? + 2.7- Should I use FLUTE or FCAST ? + 2.8- Why does the source send more packets than expected in PUSH mode ? + +3- Troubleshooting + 3.1- My receiver does not see any packet arriving + 3.2- It does not compile! + 3.3- Fcast prints "Waiting for data..." and nothing happens during several + tens of seconds, is it normal + 3.4- Sending a 1 Gigabyte fails whereas df -k tells me there's enough room + on the disk + 3.5- My receiver seems to receive the whole file normally but at the end + it hangs... + 3.6- I have strange error messages ("mcl_fsm_update_state: ERROR, event XXX + invalid in state XXX") + 3.7- The receiving FCAST fails + + +-------------------------------------------------------------------------------- + + +SECTION 1: General +------------------ + +1.1- What is MCL useful for ? +------------------------------ + +MCL is a reliable multicast library implementing the ALC (Asynchronous +Layered Coding) and NORM protocols standardized by the RMT group of the +IETF. +Both protocols are used for reliable multicast transmissions. + +ALC is of particular interest for sessions working in an "on-demand" +delivery mode (see below) or sessions where there is no (a very little) +back channel (e.g. satellite). +You can also use ALC if you are concerned by scalability aspects since +the abscence of feedback channel in ALC warrants an unlimited scalability, +or by the heterogeneity of clients. +Finally ALC is an extremely robust protocol and clients are totally +independant from one another. + +NORM requires the presence of a back channel (i.e. receivers must have +the possibility to send ACK/NACK packets to the source). This is a major +difference with ALC that can operate on strictly unidirectional networks. +Besides, NORM is limited to a "push" delivery mode, and has by nature a +limited scalability. +Yet it can easily handle the transmission of huge files, which is less +the case of ALC. + + +1.2- What are the differences between the "on-demand" (-cont arg of FCAST) +---- and "push" (default) modes ? ---------------------------------------- + +The default "push" mode requires a synchronous start: all receivers must be +ready before the session starts. It can be used for instance by a reference +server to synchronize several clients. This is the only possibility if +NORM is used (i.e. FCASTN tool). +The "on-demand" mode enables each receiver to arrive at its discretion, +download the file(s) and leave. It can be used for a scalable distribution +distribution of a popular content. It is limited to ALC (i.e. FCAST tool). + + +1.3- How can I be sure that receivers actually finished receiving the file ? +---------------------------------------------------------------------------- + +As there is no feedback flowing from the receiver to the source with ALC, +there is no mean to be sure everybody actually received the file. +Yet in "on-demand" mode a receiver will continue, listening for new packets +until it successfully downloaded the file. So the source can be optimistic. +In "push" mode there will always be a risk that the session finishes too +quickly. You can reduce this risk by asking for a predefined session extension +using the -repeatN parameter of the sending FCAST. You can for instance +ask that data is sent twice on each layer with -repeat2, thereby giving +the opportunity to finish reception even if the first transmission is not +sufficient. + +This is less true with NORM (i.e. when using FCASTN) since there are feedback +(positive and negative ACKs), but there is still a risk, for instance if a +receiver gets disconnected for a duration superior to the maximum recovery +delay of NORM. + + +1.4- I have a problem not listed, who can help me ? +--------------------------------------------------- + +You can send the description of the problem experienced to the +mcl-bugs __at__ inrialpes.fr mailing list (preferred), or send it directly +to me. + + +1.5- I already have an application and want to use MCL for the multicast +---- distribution. Is it possible ? ------------------------------------ + +Sure and this is an important asset of MCL compared to some other reliable +multicast implementations! MCL has been designed since the begining to be +a library, completely distinct from any possible upper application, with +a well defined and straightforward upper API close to the well known socket +API. It guaranties that many different applications (in addition to the ones +that are provided) can be ported/designed to use MCL. Many examples of how +to do that are provided (see for instance check/alc and check/norm +applications). + + +1.6- Is MCL's FCAST the same as Jim Gemmell's FCAST (MS) ? +---------------------------------------------------------- + +These programs are totally independant. Ours follows the ALC/LCT +specifications, uses several transmission layers, implements several +congestion control protocols, uses high performance large block FEC +codes, and is still supported... This is not the case of J. Gemmell's +FCAST. +The only relationship between the two programs is that ours is inspired +from the first ALC I-D that describes a generic transfer tool, fcast, which +forms the basis of our FCAST application... And Jim Gemmel is one of the +co-authors of this I-D ! + + +1.7- Is MCL compliant with the ALC/LCT documents and FLUTE ? +------------------------------------------------------------ + +Yes, since the early versions of MCL we always tried to keep as close as +possible to the (at that time) Internet-drafts. Now that ALC/LCT have +become IETF standards (RFC 3450-3451-3452), we did our best to make them +compliant. +Since October 2003, FLUTE conformance has been tested through interoperability +tests with two other implementations. Using the FLUTE application guaranties +a full standard compliancy (ALC, LCT, and FLUTE). +This is a little bit different with FCAST which relies on a non ALC/LCT +conformant SIG_NONEWADU Extension Header (see mcl_lct_hdr.h) (required +by the client's FSM), and FCAST itself follows a non FLUTE conformant +approach. +(see 2.7 for additional FCAST versus FLUTE comparison) + + +SECTION 2: Performances +----------------------- + +2.1- What are the maximum FCAST performances ? +---------------------------------------------- + +There is no single answer. FCAST performances really really depend on the +environment: +- Are all hosts on a LAN or on the MBONE ? Performances will be higher on + a LAN where the MTU is known (and usually higher), group add and leave + latency almost null, congestion existent (no router is crossed) even if + there can be collisions, and the "single layer" mode possible... +- What is the average loss ratio ? ALC/LCT is very sensitive to losses that + are interpreted as congestion indications and therefore trigger layer + removal. +- Is multicast routing working well ? ALC/LCT requires for optimal performances + a working multicast routing service where layers (i.e. multicast groups) + can be added and removed quickly (even if IGMP introduces some latency). + +Having said that we experimented on an idle fast Ethernet LAN (100MB), +using two dedicated PIII/1GHz/Linux(RH7.2) PCs, several FCAST transfers +of a 40MB file, using MCL version 2.1, and a Reed-Solomon FEC codec. +We experienced throughputs over 13 Mbps in on-demand mode. +This is an optimal throughput, in a situation where no loss is experienced +and that only includes the reception and FEC/application_checksum decoding +times. + + ./fcast -recv -a225.1.2.3/2323 -v0 -ospeed -plan -l10 -force + ./fcast -send -a225.1.2.3/2323 -v0 -ospeed -plan -l10 -repeat3 /tmp/file_40000000 + + +2.2- FCAST does not send packets immediately. It is normal ? +------------------------------------------------------------ + +Yes, when the application submits a new object, there is an initial FEC +packet calculation process followed by the calculation of the packet sending +(random) order in each layer. Packets will be sent over the network only +when these two steps are finished. With small files, this is not an issue, +with large files, this time can be significant, especially if our LDGM +FEC codes are not used. + + +2.3- The disk activity is very high at the sending FCAST. Is it normal ? +------------------------------------------------------------------------ + +It means that the amount of RAM devoted to store data/FEC is not +sufficient to contain the working set, and the exceeding data/FEC is +therefore stored on the disk. This is a problem if you want to do high +speed transmissions as disk I/Os may not be fast enough (MCL performs +random I/Os !). +You can improve the situation by setting the threshold to a higher value. + +in src/mcl_profile.h, set: +#define VIRTUAL_TX_MEM +#define VIRTUAL_TX_MAX_PHY_MEM_SIZE 60*1024*1024 +(or any value compatible with the amount of physical memory available +on the source) +then go to the root and compile everything: +make + +!!!WARNING: no longer available in MCL_v2.99.0 to MCL_v2.99.4 versions!!! + Will be re-enabled in future releases... + + +2.4- The disk activity is very high at the receiving FCAST. Is it normal ? +-------------------------------------------------------------------------- + +The situation is similar to question 2.3. Yet this is less a problem at +a receiver, even in case of high speed transmissions, as disk I/Os are +sequential during the reception process. This is only penalizing during the +FEC decoding process. +You can improve the situation by setting the threshold to a higher value. +(same method as in answer 2.3, with the VIRTUAL_RX_MEM and + VIRTUAL_RX_MAX_PHY_MEM_SIZE constants instead). + +!!!WARNING: no longer available in MCL_v2.99.0 to MCL_v2.99.4 versions!!! + Will be re-enabled in future releases... + + +2.5- How can I improve the FCAST performances ? +----------------------------------------------- + +There are several ways to improve FCAST performances (in decreasing +importance order): + +- use our large block LDPC/LDGM FEC codec (default in pre-compiled versions). + +- increase the maximum block size supported by our LDPC/LDGM codec + (src/alc/mcl_profile.h). For instance: + #ifdef LDPC_FEC + #define LDPC_DEFAULT_K 40*1000 /* at most 40*10^3 packets */ + #define LDPC_DEFAULT_N 80*1000 /* at most 80*10^3 packets */ + #endif + Doing this requires you have enough RAM for encoding/decoding... + +- if you are on a LAN, use the -plan profile at both the source and receivers + (in particular FCAST will use a single layer which significantly reduces + duplicates at the receiver) + +- if you are on the Internet, then try the -phigh profile... and use -pmed + if receivers experience too many losses. Otherwise use the -psize/rate + manual transmission rate control. + +- if you are not in single layer mode (in particular if you are not using + -plan), then increase the FEC expansion ratio (default is 1.5, i.e. 50% + of additional parity packets). A value of 2.0 largely improves the overall + performance since it creates additional FEC packets, and therefore reduces + the probability of having duplicates among the layers.. Yet having higher + FEC expansion ratios requires to have a higher amount of RAM memory... A + good balance must be found here. + +- try to increase the RAM storage threshold as explained in answers 2.3 and + 2.4. This is of utmost importance at the source. + +- try the -ospeed optimization profile at both the source and receivers. + If receivers experience too many losses, and if you suspect they can be + CPU bounded, then try the -ocpu optimization profile. + +- make sure you compiled everything in optimized mode (edit all Makefiles) + +- do not use NFS volumes for instance as the source or destination file + location. + +To have an idea of the global decoding inefficiency, you can use the -stat1 +(or -stat2) argument at the receiver and look at the global_ineff_ratio +value. For instance, in -plan mode we experienced global_ineff_ratio=1.015, +meaning that only 1.5% of packets in addition to the strict minimum (i.e. oject +size) were required to do decoding. But between the same hosts, in -phigh +mode and the default 1.5 FEC expansion ratio, we experienced: +global_ineff_ratio=1.457, which falls down to: global_ineff_ratio=1.118 +(i.e. 11.8% of additional packets) if we specify a 2.5 FEC expansion ratio +at the source. + + +2.6- Why is the standard FTP X times faster than FCAST ? +-------------------------------------------------------- + +FTP uses TCP which is a point to point protocol and therefore creates a +strong association between the source and the receiver, with feedback +information. +On the opposite, MCL cannot use any feedback information from the receivers +and cannot adapt it flow to each receiver individually. +This is why when there is a single receiver multicast is necessarily +less performant than unicast ! That's different in case of a high number +of receivers. + + +2.7- Should I use FLUTE or FCAST ? +---------------------------------- + +FLUTE is a standard. +FCAST is a proprietary tool coming from an old version of the ALC document +(see draft-ietf-rmt-pi-alc-01.txt, mirrored in the MCLv3 site). +The major difference between the two tools come from the way file meta-data +is carried within the ALC session: +- with FLUTE meta-data are carried as a separate ALC object +- with FCAST meta-data are carried within the file object. + +FCAST's implementation is simpler (no need for XML parsing), and +perfectly suited to situations where ALL clients are interested by +ALL the objects sent within a given ALC session. + +FLUTE implementation is much more complex (e.g. it relies on an XML +parsing tool, currently Xerces). For simple situations, FCAST will +be more efficient. But (1) FLUTE is a standard, and (2) FLUTE can be +used in situations where FCAST is totally inappropriate. For instance, +if the objects sent within a FLUTE session are largely different, and if +clients may be interested by a subset of them only, FLUTE enables each +to filter packets of interest upon reception, which leads to major +memory and processing saving. + +(see 1.7 for additional FCAST versus FLUTE comparison) + + +2.8- Why does the source send more packets than expected in PUSH mode ? +----------------------------------------------------------------------- + +This is perfectly normal, even if you don't use the -repeat parameter +of either FCAST or FLUTE (both tools behave in the same way from this point +of view). In PUSH mode, we have added an optimization which consists +in starting source packet transmissions sequentially, at the very begining +of the session, while doing FEC encoding. This is an easy way of: (1) hiding +calculation behind transmissions, that start earlier, and (2) reducing the +download time at a receiver, especially if this latter experiences no packet +loss. Only when this sequential transmission stops does the source continue +by sending (a random permutation of) the source and FEC packets on the +various layers, as expected. +So in PUSH mode and if "-repeat" is not used, there will be, in case the +file is small enough to be encoded as a single block of k packets: + k (seq. tx.) + nb_of_layers * (FEC_ratio * k) +packets sent, where FEC_ratio is specified with the "-fec" argument. + +This behavior does not take place in on-demand mode (meaningless). It can +also be invalidated by avoiding to define the following macro +(src/alc/mcl_profile.h): +/* #define ANTICIPATED_TX_FOR_PUSH */ +and recompilling the tools. + + +SECTION 3: Troubleshooting +-------------------------- + +3.1- My receiver does not see any packet arriving +------------------------------------------------- + +There are two possible reasons: + +- if your source and receiver are not on the same LAN, i.e. if multicast + routing is required, make sure the TTL used by the source is high enough. + You can slowly increase the TTL using the -tN parameter. Remember that by + default FCAST uses a TTL equal to 1, assuming everybody is on the same + LAN ! + +- if your receiver is a multi-homed host (i.e. a host with several physical + interfaces), or a router, then it is possible that he does not listen + multicast packets on the right interface. In that case, use the -ifN + option of FCAST (release 2.1.1 or higher): + + -ifn the network interface to use is the one attached to the + local address n (only used on multi-homed hosts/routers) + (you can use either a hostname or an IP address) + + For instance, on router A, with two Ethernet cards, eth0 with IP + 194.199.33.12 and eth1 with IP 194.199.34.25, you can start FCAST + with -if194.199.33.12 to receive multicast packets from interface eth0, + with -if194.199.34.25 to receive from interface eth1. + + +3.2- It does not compile! +------------------------- + +Two possibles reasons are: +- you don't use GNU make +- you don't have makedepend + +1/ The MCL (and associated application) building process requires the use +of the GNU Make tool. This version of Make (e.g. natively included in +Linux distributions) provides several usefull extensions to the standard +Make tool (e.g. the one provided natively with the Sun/Solaris OS). +If you don't have the GNU version of make you can: + +- retrieve and install GNU Make from the official site (recommanded). + http://www.gnu.org/software/make/make.html + It is available in binary format for most OS which means it should not be + too difficult to install. + +- change all the MCL makefiles to avoid the use of gmake. + In short you should: + - copy the top Makefile.common file in the various Makefiles and + therefore remove the "include ../Makefile.common" instruction of + these Makefiles, + - select the appropriate lines corresponding to your OS, remove the + other ones as well as the "ifeq (${OS},solaris)" (or similar lines). + +2/ Compiling also requires the makedepend tool to update the various +header dependancies in the various Makefiles (this is why these Makefiles +have the following lines: +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. +Yet it is also possible that the makedepend tool is not available on your +system (e.g. on RH Linux, it is only available if the XFree86-devel rpm has +been installed!). In that case you can: + +- either remove the "${MAKE} depend" section of the top Makefile, +- with Linux, install the XFree86-devel rpm, or +- use a perl version of the makedepend tool, which saves the need to + install any package and runs on all systems having perl! + + +3.3- Fcast prints "Waiting for data..." and nothing happens during several + tens of seconds, is it normal? -------------------------------------- +------------------------------------ + +This is perfectly normal, except that packets may be received even if fcast +does not see them. In fact packets are received by the ALC/LCT layer (within +the MCL library) and are only returned to the Fcast receiving application +when a file fragment has been completely received which may take time. +If you want to make sure that reception occurs, you should run the receiving +fcast in verbose mode (-v1 is sufficient). +Otherwise use top, you'll see the fcast size growing regularly when packets +are effectively received (they are first stored in memory). +Then, if the memory buffer (of limited size) turns full, additional packets +will be stored in the temporary file, so have a look at file /tmp/mcl_vtm_*, +you'll see it growing regularly. + + +3.4- Sending a 1 Gigabyte fails whereas df -k tells me there's enough room + on the disk --------------------------------------------------------- +---------------- + +File systems have file-size limitations, usually 2^31 bytes (this is what +happens on my Linux RH-6.2 host), and 2^31 is 2.147.483.648 bytes, that +is to say a bit more than 2 Gigabytes (with giga meaning 10^9). +As MCL uses a temporary file to store both data and FEC symbols, this +file quickly grows... until it's too large! +With huge files make sure that you use an appropriate FEC ratio +(-fec2) at the sending source, as it directly impacts the temporary +file size. +The solution is known (use the Large File I/O API) but we didn't found +time so far to do the work... + + +3.5- My receiver seems to receive the whole file normally but at the end + it hangs... ------------------------------------------------------- +----------------- + +By default the receiving FCAST tool is interactive, and asks for the +permission before overwritting an already existing file. If you are +in verbose mode, you may not have seen the question: +File "foo.bar" exists, overwrite? [y/n] +In that case type y ... +You can also use the -force or -never option at the received, depending +on what you want. See the FCAST man... + + +3.6- I have strange error messages ("mcl_fsm_update_state: ERROR, event XXX + invalid in state XXX") ----------------------------------------------- +---------------------------- + +This occurs when the Finite State Machine (FSM) controlling the sending +and receiving sessions encounters an event in an non-appropriate state. +It usually takes place when two sessions get mixed, e.g. when a previous +incarnation of a sender keeps sending packets when a new sender is +restarted (with the same parameters). +You can avoid it by using a different TSI (transport session identifier) +on each incarnation of MCL or FCAST. +You can also use a different address and/or port number range. + + +3.7- The receiving FCAST fails +------------------------------ + +Most problems of this kind are due to a mismatch in the sender and +receiver FCAST arguments. Check in particular the transmission profiles +(-pXXX, -singlelayer, -psize). Since for instance the packet size is +not communicated in any way by MCL, the receiver often truncates the +incoming packets, and either FEC decoding or the FCAST checksum +verification fail. + diff --git a/doc/RELEASE_NOTES b/doc/RELEASE_NOTES new file mode 100644 index 0000000..acdafc0 --- /dev/null +++ b/doc/RELEASE_NOTES @@ -0,0 +1,467 @@ + $Id: RELEASE_NOTES,v 1.29 2005/05/24 15:43:21 roca Exp $ + + ----------------------------------------------------- + MCL LIBRARY RELEASE NOTES - vincent.roca@inrialpes.fr + ----------------------------------------------------- + + +Supported functionalities +------------------------- + +The following table lists the supported functionalities in the +various releases... + + Functionalities library version number + 2.3 2.4 2.99 2.991 2.992 2.993 2.994 2.995 2.996 +------upper interface-----------------|----|----|----|-----|-----|-----|-----|-----|-----| +scatter/gather support | NO | NO | NO | NO | NO | NO | P | P | Y | +FLUTE API | NO | NO | NO | NO | NO | NO | NO | NO | Y | + | | | | | | | | | | +------networking----------------------|----|----|----|-----|-----|-----|-----|-----|-----| +IPv6 support | NO | NO | NO | NO | NO | NO | P | Y | Y | +IPv4 SSM (Source Specific Multicast) | NO | NO | NO | NO | NO | NO | NO | NO | Y | +IPv6 SSM (Source Specific Multicast) | NO | NO | NO | NO | NO | NO | NO | NO | P | + | | | | | | | | | | +------reliability---------------------|----|----|----|-----|-----|-----|-----|-----|-----| +FEC (reed-solomon) for reliability | Y | Y | Y | Y | Y | Y | Y | Y | Y | +LDGM large block FEC codec | NO | NO | Y | Y | Y | Y | Y | Y | Y | + | | | | | | | | | | +------ALC/LCT functionalities---------|----|----|----|-----|-----|-----|-----|-----|-----| +ALC (Asynch Layered Coding) compliant | Y | Y | Y | Y | R | Y | Y | Y | Y | +LCT (Layered Coding Transp) compliant | Y | Y | Y | Y | E | Y | Y | Y | Y | +virtual transmission memory service | Y | Y | Y | NO | M | NO | NO | NO | NO | +virtual reception memory service | Y | Y | Y | NO | O | NO | NO | NO | Y | +congestion control (RLC) | Y | Y | Y | Y | V | Y | Y | Y | Y | +congestion control (FLID-SL) | Y | Y | Y | Y | E | Y | Y | Y | Y | +select() support | P | P | Y | Y | D | Y | Y | Y | Y | +1->n with feedback n->1 | Y | Y | NO | NO | ! | NO | NO | NO | NO | +m->n support (can be both tx and rx) | NO | NO | NO | NO | ! | NO | NO | NO | NO | +support of file size >> memory size | Y | Y | NO | NO | ! | NO | NO | NO | NO | + | | | | | | | | | | +------NORM functionalities------------|----|----|----|-----|-----|-----|-----|-----|-----| +NORM support included | NO | NO | NO | NO | Y | Y | Y | Y | Y | +NORM compliant | NO | NO | NO | NO | NO | NO | NO | NO | NO | +congestion control (pgmcc/tfmcc) | NO | NO | NO | NO | NO | NO | NO | NO | NO | + | | | | | | | | | | +------applications--------------------|----|----|----|-----|-----|-----|-----|-----|-----| +flute compliant | NO | NO | NO | P | NO | Y | Y | Y | Y | +fcast application | Y | Y | Y | Y | Y | Y | Y | Y | Y | +windows fcast GUI frontend | Y | Y | Y | Y | Y | Y | Y | NO | NO | +robcast application | NO | NO | Y | Y | Y | Y | Y | Y | Y | + | | | | | | | | | | +------system--------------------------|----|----|----|-----|-----|-----|-----|-----|-----| +linux support | Y | Y | Y | Y | Y | Y | Y | Y | Y | +solaris support | Y | Y | Y | Y | Y | Y | Y | Y | Y | +freebsd support | NO | NO | NO | P | NO | P | Y | Y | Y | +windows XP (visual C++) | Y | Y | Y | Y | NO | P | P | Y | Y | + | | | | | | | | | | + +Y: yes (validated) +P: partial (not fully validated or including known bugs or important + limitations) +NO: not available + + +Notes for MCLv3 release 2.99.6 - May, 2005. +----------------------------------------------------- + +This is a major version with many changes for the ALC and +FLUTE part: +- Creation of a C++ FLUTE API. The Flute application is now a small application + built on top of the FLUTE API. Writting your own application on top of this + FLUTE API enables a full and dynamic control of the FLUTE/ALC session, e.g. to + add transmission cycles to the carousel, add/remove files to the carousel, and + many other things. Extending the example Flute application to add new + functionalities is both feasible and straightforward. +- Receivers are no longer limited by their RAM size (receiving files whose + size is an order of magnitude larger than the host's RAM is feasible). + This is made possible by a dedicated virtual receive memory management scheme. +- IPv4 SSM (source specific multicast) is now supported. +- IPv6 SSM (source specific multicast) is now supported (Linux with 2.6.x + kernels, tested with FC2 and FC3 distributions). +- Added automatic MCLv3-FLUTE versus MAD-FLUTE interoperability validation + scripts. + + +2/ NORM part: +- No change. + +Dependancies: requires LDPC v1.8; only tested with Xerces-C++ v2.6.0 + + +Notes for MCLv3 release 2.99.5 - December 21st, 2004. +----------------------------------------------------- + +This is a major version with many changes for the ALC and +FLUTE part. We consider it is a stable version. +1/ ALC part: +- Largely improved FLUTE application: + * FLUTE is now based on Xerces-c, the XML library of the Apache + Software Foundation (view README for build instructions) + * FLUTE runs on all platforms, including Windows, FreeBSD, Solaris, + and iPAQ/Linux (!) + * Many FLUTE internal improvements + * Improved performances at a receiver (one data copy less thanks + to the mcl_recvmsg() function) + * Added a reception meter for each file sent within the session + * Added FLUTE man page (and updated FCAST's man page too) +- IPv6 support on Windows platforms +- Congestion control protocol can now be selected at runtime + (rather than preset at compilation time). +- Short LCT header fields (16 bits) for the TOI and TSI fields + are now supported and used whenever possible. +- AIX, IRIX, HP-UX support added (thanks to Florian Geyer). + Not fully tested though. +- Many bugfixes +- Warning: -singlelayer argument of FCAST/FLUTE is replaced by the -cc0 + argument (i.e. no congestion control) +2/ NORM part: +- No change. + +Dependancies: only tested on LDPC v1.7 and Xerces-C++ v2.6.0 + + +Notes for MCLv3 release 2.99.4-unstable - October 4th, 2004. +------------------------------------------------------------ + +This is a major version with many changes for the ALC part. Due to the +high number of changes, we consider it is an unstable version. +1/ ALC part: +- Added IPv6 support (only tested with FreeBSD; does not work yet + with Windows) +- Improved LDGM-* support (results in significant memory savings). +- Added an object aggregation scheme for improved efficiency when + sending a large number of small objects. +- Completely re-wrote a great part of the internal ALC library + (even if not finished) and removed a lot of historical code. +- Added mcl_recvmsg for scattering I/O. +2/ NORM part: +- No major changes, only cosmetic improvements. + + +Notes for MCLv3 release 2.99.3b - March 9th, 2004. +-------------------------------------------------- + +This is the first release where NORM and ALC codes are both integrated. +1/ ALC part: +- This release requires LDPC_v1.3 (February 25th, 2004). +- ALC/LCT/FLUTE compliant. Interoperability has been checked with three other + implementations. +- many improvements (in particular new blocking algorithm both at ALC and + FCAST, better FEC support, supports FEC Encoding ID 129 when used with + small block FEC (not recommended though)) +- FLUTE application improvements (yet FCAST remains the prefered, most + stable application), but it is still not available under Windows. +- FCAST automatically chooses between Reed-Solomon and LDGM FEC depending + on each file size, so both codecs may be used in the same session. +- FLID-SL is the new congestion control default (yet MCLv3 can be + compiled with RLC support if needed by changing src/alc/mcl_profile.h file). + Many cleanups in FLID code. +- FreeBSD support added (thanks to Panagiotis Astithas). Not fully tested + though. +2/ NORM part: +- removed many memory leaks (thanks to George Coulouris) +- still rather experimental and non conformant... Use with great care! + + +Notes for MCLv3 release 2.99.2 - December 19th, 2003. +----------------------------------------------------- + +This is the first release of the NORM code. +The current NORM protocol is still very very experimental (not fully tested) +and does not conform to the latest NORM document (and only loosely to previous +ones)! +So only use it if you want to have a first feeling of what NORM support will +look like in the future... +- added NORM code... +- ...and removed ALC code from this release! +- only tested on Linux/Solaris, no Windows support yet for NORM. +- the same FCAST application has been updated to run on both ALC and NORM. + + +Notes for MCLv3 release 2.99.1 - November 24th, 2003. +----------------------------------------------------- + +This is the second pre-MCLv3 release. +This release includes both RSE and LDGM-staircase which is the new default. +The LDGM-staircase source distribution (version 1.1 required) is available +separately. + +- added FLUTE support (see draft-ietf-rmt-flute-04.txt). + This version is currently only available for Linux, and assumes gdome2 + has been installed on your host. It is still experimental (some + limitations are known for this release), take it into account... +- successful interoperability tests have been carried out with two other + ALC/FLUTE implementations, but this is not the end of the story... +- LDGM-staircase is fully integrated and is the new default FEC codec. + Using this codec largely improves performances. + Yet if Linux/Solaris interoperate, because of the use of a different + srand()/rand() algorithms, Win32 tools using LDPC do not interoperate + with the corresponding Unix versions. +- we changed the -plan profile of FCAST! It now defines a single layer + (unlike other -plow/med/high profiles). Consequently there is no + congestion control when -plan is used (it's useless within a LAN!) + and you shouldn't use it if routers are crossed... +- many things have been clarified/improved in the source code, and several + bug corrected +- NORM, currently under progress, is still not integrated in this release +- the -phuge profile is no longer supported with the LDGM codec and by + default is undefined (enable the #define in mcl_profile.h if you want to + use it using Reed-Solomon) + + +Notes for MCLv3 release 2.99.0 - July 22nd, 2003. +------------------------------------------------- + +This is the first pre-MCLv3 release. +Many things are new, including the distribution tree. +In this release, only RSE is included by default. +LDPC/LDGM is available separately and can be used in MCLv3, but at your +own risks (LDGM integration is not finished, performances are often +behind those of RSE, and Linux/Solaris interoperability is bad). +Yet interested people can download the LDPC package, set the LDPC define +in src/alc/mcl_profile.cpp, and compile everything (make alc; at the top +directory). The NORM component is not available in this release (still +under development...). + +- new distribution tree, with ALC/LCT and NORM sub-directories + (NORM, currently under progress is not integrated in this release) +- progressive move from C to C++ and full reorganization of source files + is under progress. GCC is no longer supported, we use G++ instead. +- new LDGM large block FEC codec partially integrated, but still + very experimental. +- new RobCast application available to illustrate how ALC/LCT can be + used for a client/server application robust to any number of restart + of the client and/or the server application (thanks to Eric Nicolas). +- various bug corrections. + + +Notes for release 2.4 - February 12th, 2003. +-------------------------------------------- + +- added the -singlelayer profile to FCAST and MCL. Enables an efficient use + of FCAST in closed/well known environments, where congestion control is not + required (e.g. satellites). Congestion control is not used then, so do not + use this mode when using FCAST over the Internet. + This mode is compatible with the -o[speed|space|cpu] and -p[low|mid|high|lan] + profiles. +- added the -p datagram_size[/rate] argument to FCAST. Usefull to create + profiles other than those of p[low|mid|high|lan] +- fixed a bug in FCAST when stopped with CTRL-C +- various minor MCL improvements +- FcastWin Application updated for new features (v1.1) + + +Notes for release 2.3 - Oct 1st, 2002. +------------------------------------------ + +- Some bugs have been reported and/or found in mcl and in the fcast tool, so 2.3 is a bug fixes release. +- Improved some sockets and threads aspects in the WIN32 Version of fcast and mcl. +- Added a new fcast test for single file without path in the validation scripts (check/). + + +Notes for release 2.2.2 - Sept 20th, 2002. +------------------------------------------ + +- the MCL library is now distributed under a GNU LGPL (lesser GPL) license + to enable its use in private applications. The upper applications are still + distributed under a GNU GPL license. +- fixed a bug in Fcast Tool (when overwriting, file was not tuncated if old file was bigger than new one) +- +some minor updates. + + +Notes for release 2.2.1 - May 30th, 2002. +----------------------------------------- + +This is essentially a bug fix release, the only big change being the fcast +frontend: +- added a graphical Windows frontend to fcast: FcastWin (beta version) +- fixed a bug when using several sessions +- fixed memory leak problem (thanks to Liu) +- fixed two fd leak problem (thanks to Xin Liu) +- fixed few bugs in the fcast application. +- added several validation programs +- added compliancy with alc-07 draft + + +Notes for release 2.2 - March, 2002. +------------------------------------ + +A major release, including several major improvements: +- new packet scheduling for improved sequential disk accesses. Usefull for + the high speed transmission of files whose size >> physical memory size. + We succeeded in transmitting a 1GB file between two PIII/1GHz/Linux PCs + at a 4.174 Mbps rate in "push" mode ("read from disk/coding/transmission/ + decoding/write to disk" times included). +- reduced burstiness at the sending side +- addition of FLID-SL (static layer) congestion control. Still a bit + experimental in this release. Use with care and prefer RLC in hard + environments!!! +- improved performances, essentially noticeable with very large files +- the can be specified with FCAST to precisely + identify the ALC session and filter incoming packets + + +Notes for release 2.1.1 - January 5th, 2002. +--------------------------------------------- + +- added -ifn option to FCAST for multi-homed hosts and routers. +- Using a dedicated testbed (100mbps Ethernet, two PIII/1GHz/Linux PCs) and + 40MB files, we achieved up to 13.6 Mbps transmission rates. +- several cleanups and minor corrections +We believe this version is mature enough to be used in operational environments! + + +Notes for release 2.1.0 - November 6th, 2001. +--------------------------------------------- + +- LCTv2 and ALCv3 compliancy +- improved performances + Up to 3.5Mbps in PUSH mode with a 40MB file on a LAN (includes coding, + transfer and decoding time) and 4.0Mbps in ON-DEMAND with + the same file on a LAN (only includes transfer and decoding time). + Uses two PIII/700/Linux PCs. + After changing the ANTICIPATED_TX_FOR_PUSH_AGGRESSIVENESS parameter to favor + high end receivers, up to 6.8Mbps in PUSH mode on a LAN with the same file + and same hosts. + These are optimal throughput, in situations where no loss is experienced! + Parameters: + ./fcast -recv -a225.1.2.3/2323 -v0 -ospeed -plan -force + ./fcast -send -a225.1.2.3/2323 -v0 -ospeed -plan -repeat3 /tmp/file_40000000 +- several cleanups and minor corrections +- works (again) under windows2000 + + +Notes for release 2.0.6 - October 2nd, 2001. +--------------------------------------------- + +Many important improvements... +- many many performance improvements: ~2.4Mbps in PUSH mode with a + 40MB file on a LAN, with two PIII/700/Linux PCs, using the following + parameters: + ./fcast -recv -a225.1.2.3/2323 -v0 -plan -ospeed -force + ./fcast -send -a225.1.2.3/2323 -v0 -plan -ospeed -fec2 -l6 /tmp/file_40000000 + (and reception rates above 3Mbps have been experienced with smaller files) +- improved time management in the transmission thread (derived from + code provided by Benoit. Thanks!) +- fcast is now fully functional (e.g. it supports recursive mode) + +Limitation: no longer works with Windows (will be soon corrected) + + +Notes for release 2.0.5 - July 27th, 2001. +------------------------------------------- + +Some improvements... +- support of CPU optimization mode in fcast/MCL. +- improved support of Virtual Transmission/Reception + Memory service. +- fixed several bugs in fcast. +- added new fcast validation scripts. +- fcast recursive mode is still unavailable (will be fixed + in the next release). + + +Notes for release 2.0.4 - July 9th, 2001. +------------------------------------------ + +Several improvements... +- supports disk storage of incoming packets on the receiving side +- traces can be sent to a file rather than on stdout/stderr +- includes a validation tool that produces ill-formed packets, to + check that a receiver identifies the problem suitably + + +Notes for release 2.0.3 - June 11th, 2001. +------------------------------------------ + +A major release... +- MCL is now LCT (Layered Coding Transport) compliant! +- added a virtual transmission memory service to allow the transmission + of very large objects +- added manual pages +- the fcast application now includes several high level optimisations + (tx profile for low/medium/high rates and space versus speed optimization) +- added the MCL_OPT_POSTPONE_FEC_DECODING mode (very usefull to optimize + reception times with high speed connections and/or slow FEC codecs. +- added various other object/symbol scheduling modes + + +Notes for release 2.0.1 - January 2001. +--------------------------------------- + +An important evolution of 2.0.pre_alpha: +- more supported platforms (including WindowsNT 4.0) and several + C/C++ compilers. +- multiple sessions can be defined within a single MCL instance (i.e. an + application) +- many internal major redesign and improvements +- full memory cleanup + + +Notes for release 2.0.pre_alpha - October 2000. +----------------------------------------------- + +This is a major release! +- MCL is now ALC (Asynchronous Layered Coding) compliant! +- Fcast (multicast file transfer) as defined in ALC i-draft +- object/block/symbol supported +- delivery of ADUs in arrival order now supported +- many internal major redesign and improvements + + +Notes for release 1.2 - July 27th, 2000. +---------------------------------------- + +- ODL support added (see http://www-rp.lip6.fr/~roca/mcl/) +- RLC support added for multicast congestion control +- internal major redesign + + +Notes for release 1.1 - January 6th, 2000. +------------------------------------------ + +- added a FSM (Finite State Machine) +- added functions to add/drop a layer (can be called e.g. by a congestion + control module) (only available with GMMG scheduling) +- a host can at the same time receive and transmit in unicast over an MCL + endpoint (feedback of each receiver as with bench[d] in RTT mode). +- support the select() syscall of the Socket API to wait on MCL and/or + other non MCL endpoints (i.e. on a standard socket) (not fully tested yet!) + +Known problems (in addition to limitations listed in the table): + +- DSS/plain schedulings are provisoirely broken in this version + + +Notes for release 1.0 - October 22, 1999. +----------------------------------------- + +Many improvements in this release: + +- comes with the bench traffic generator, modified to use the library API +- DSS sched now works normally +- a basic scheduling (called plain sched) is available. Consists in a single + layer where packets are sent in sequence +- signalization redundancy has been improved. Data packets are now + self-sufficient even if new ADUs are still announced as soon as possible +- improved statistics +- tested on Linux (see note for release 0.9b) and Solaris 2.5.1/2.6 + +Known problems (in addition to limitations listed in the table): + +- very large memory consumption at the sending side (no freeing policy yet) +- no session nore configuration announcement + + +Notes for release 0.9beta - July 22, 1999. +------------------------------------------ + +First public release. +This is still beta code and many aspects are still not supported. +Yet you can use it with the internal application (we still have a few +problems with the external bench application). +Currently it has only been tested on Linux (RedHat5.x/standard 2.0.3x +kernels plateforms). +(NB: beware of multicast compilation options if you build a personal kernel!) + diff --git a/doc/doxygen/alc/Doxyfile b/doc/doxygen/alc/Doxyfile new file mode 100644 index 0000000..7f0d62b --- /dev/null +++ b/doc/doxygen/alc/Doxyfile @@ -0,0 +1,970 @@ +# Doxyfile 1.2.17 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = mclv3 + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +#STRIP_FROM_PATH = /mnt/iseran/roca/work/mclv3/ +STRIP_FROM_PATH = /home/roca/work/mclv3/ + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consist of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../../../src/alc ../../../src/common + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output dir. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non empty doxygen will try to run +# the html help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the Html help documentation and to the tree view. + +TOC_EXPAND = YES + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, +# or Internet explorer 4.0+). Note that for large projects the tree generation +# can take a very long time. In such cases it is better to disable this feature. +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yield more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermedate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/doc/doxygen/alc/html/classmcl__cb__coll__graph.dot b/doc/doxygen/alc/html/classmcl__cb__coll__graph.dot new file mode 100644 index 0000000..12da9ee --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__cb__coll__graph.dot @@ -0,0 +1,64 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_cb",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fsm",fontname="Helvetica"]; + Node2 [label="mcl_fsm",height=0.2,width=0.4,color="black",URL="$classmcl__fsm.html"]; + Node3 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket_tab",fontname="Helvetica"]; + Node3 [label="mcl_socket",height=0.2,width=0.4,color="black",URL="$classmcl__socket.html"]; + Node4 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node4 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node5 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rxlvl",fontname="Helvetica"]; + Node5 [label="rxlay_t",height=0.2,width=0.4,color="black",URL="$structrxlay__t.html"]; + Node6 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node6 [label="du",height=0.2,width=0.4,color="black",URL="$structdu.html"]; + Node6 -> Node6 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node7 -> Node6 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="pkt",fontname="Helvetica"]; + Node7 [label="mcl_rx_pkt",height=0.2,width=0.4,color="black",URL="$classmcl__rx__pkt.html"]; + Node8 -> Node6 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node8 [label="block",height=0.2,width=0.4,color="black",URL="$structblock.html"]; + Node6 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node9 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node9 [label="adu",height=0.2,width=0.4,color="black",URL="$structadu.html"]; + Node8 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node9 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node4 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node3 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket_head",fontname="Helvetica"]; + Node10 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_flute",fontname="Helvetica"]; + Node10 [label="mcl_rx_flute",height=0.2,width=0.4,color="black",URL="$classmcl__rx__flute.html"]; + Node11 -> Node10 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="desired_tois",fontname="Helvetica"]; + Node11 [label="mcl_toi_list",height=0.2,width=0.4,color="black",URL="$structmcl__toi__list.html"]; + Node11 -> Node11 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node12 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_window",fontname="Helvetica"]; + Node12 [label="mcl_rx_window",height=0.2,width=0.4,color="black",URL="$classmcl__rx__window.html"]; + Node9 -> Node12 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head\nnext_ordered_adu_to_return",fontname="Helvetica"]; + Node13 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_flute",fontname="Helvetica"]; + Node13 [label="mcl_tx_flute",height=0.2,width=0.4,color="black",URL="$classmcl__tx__flute.html"]; + Node14 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="txlay_tab",fontname="Helvetica"]; + Node14 [label="txlay",height=0.2,width=0.4,color="black",URL="$structtxlay.html"]; + Node3 -> Node14 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket",fontname="Helvetica"]; + Node15 -> Node14 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_tab\ntx_tab_high",fontname="Helvetica"]; + Node15 [label="mcl_tx_tab",height=0.2,width=0.4,color="black",URL="$classmcl__tx__tab.html"]; + Node16 -> Node15 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="cached_txtab\ntxtab_head",fontname="Helvetica"]; + Node16 [label="txtab",height=0.2,width=0.4,color="black",URL="$structtxtab.html"]; + Node6 -> Node16 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_tab",fontname="Helvetica"]; + Node16 -> Node16 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node17 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="stats",fontname="Helvetica"]; + Node17 [label="stats_t",height=0.2,width=0.4,color="black",URL="$structstats__t.html"]; + Node18 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fec",fontname="Helvetica"]; + Node18 [label="mcl_fec",height=0.2,width=0.4,color="black",URL="$classmcl__fec.html"]; + Node19 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="periodic_proc",fontname="Helvetica"]; + Node19 [label="mcl_periodic_proc",height=0.2,width=0.4,color="black",URL="$classmcl__periodic__proc.html"]; + Node9 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="findadu_cache\nlastadu_cache",fontname="Helvetica"]; + Node20 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="sig_tab\npsig_next",fontname="Helvetica"]; + Node20 [label="sig_tab",height=0.2,width=0.4,color="black",URL="$structsig__tab.html"]; + Node4 -> Node20 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="saddr",fontname="Helvetica"]; + Node20 -> Node20 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node4 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr\nmcast_if_addr\nsrc_addr",fontname="Helvetica"]; + Node21 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx",fontname="Helvetica"]; + Node21 [label="mcl_tx",height=0.2,width=0.4,color="black",URL="$classmcl__tx.html"]; + Node9 -> Node21 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_start\nadu_head\nadu_end",fontname="Helvetica"]; + Node22 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_storage",fontname="Helvetica"]; + Node22 [label="mcl_rx_storage",height=0.2,width=0.4,color="black",URL="$classmcl__rx__storage.html"]; +} diff --git a/doc/doxygen/alc/html/classmcl__cb__coll__graph.md5 b/doc/doxygen/alc/html/classmcl__cb__coll__graph.md5 new file mode 100644 index 0000000..b8506d9 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__cb__coll__graph.md5 @@ -0,0 +1 @@ +70b8de872231a80981bf2d6480c2dedf \ No newline at end of file diff --git a/doc/doxygen/alc/html/classmcl__meta__object__coll__graph.dot b/doc/doxygen/alc/html/classmcl__meta__object__coll__graph.dot new file mode 100644 index 0000000..fc4f2d6 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__meta__object__coll__graph.dot @@ -0,0 +1,65 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_meta_object",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="mclcb",fontname="Helvetica"]; + Node2 [label="mcl_cb",height=0.2,width=0.4,color="black",URL="$classmcl__cb.html"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fsm",fontname="Helvetica"]; + Node3 [label="mcl_fsm",height=0.2,width=0.4,color="black",URL="$classmcl__fsm.html"]; + Node4 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket_tab",fontname="Helvetica"]; + Node4 [label="mcl_socket",height=0.2,width=0.4,color="black",URL="$classmcl__socket.html"]; + Node5 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node5 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node6 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rxlvl",fontname="Helvetica"]; + Node6 [label="rxlay_t",height=0.2,width=0.4,color="black",URL="$structrxlay__t.html"]; + Node7 -> Node6 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node7 [label="du",height=0.2,width=0.4,color="black",URL="$structdu.html"]; + Node7 -> Node7 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node8 -> Node7 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node8 [label="block",height=0.2,width=0.4,color="black",URL="$structblock.html"]; + Node7 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node9 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node9 [label="adu",height=0.2,width=0.4,color="black",URL="$structadu.html"]; + Node8 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node9 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node5 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node4 -> Node6 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket_head",fontname="Helvetica"]; + Node10 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_flute",fontname="Helvetica"]; + Node10 [label="mcl_rx_flute",height=0.2,width=0.4,color="black",URL="$classmcl__rx__flute.html"]; + Node11 -> Node10 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="desired_tois",fontname="Helvetica"]; + Node11 [label="mcl_toi_list",height=0.2,width=0.4,color="black",URL="$structmcl__toi__list.html"]; + Node11 -> Node11 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node12 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_window",fontname="Helvetica"]; + Node12 [label="mcl_rx_window",height=0.2,width=0.4,color="black",URL="$classmcl__rx__window.html"]; + Node9 -> Node12 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head\nnext_ordered_adu_to_return",fontname="Helvetica"]; + Node13 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_flute",fontname="Helvetica"]; + Node13 [label="mcl_tx_flute",height=0.2,width=0.4,color="black",URL="$classmcl__tx__flute.html"]; + Node14 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="txlay_tab",fontname="Helvetica"]; + Node14 [label="txlay",height=0.2,width=0.4,color="black",URL="$structtxlay.html"]; + Node4 -> Node14 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket",fontname="Helvetica"]; + Node15 -> Node14 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_tab\ntx_tab_high",fontname="Helvetica"]; + Node15 [label="mcl_tx_tab",height=0.2,width=0.4,color="red",URL="$classmcl__tx__tab.html"]; + Node16 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="stats",fontname="Helvetica"]; + Node16 [label="stats_t",height=0.2,width=0.4,color="black",URL="$structstats__t.html"]; + Node17 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fec",fontname="Helvetica"]; + Node17 [label="mcl_fec",height=0.2,width=0.4,color="black",URL="$classmcl__fec.html"]; + Node18 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="periodic_proc",fontname="Helvetica"]; + Node18 [label="mcl_periodic_proc",height=0.2,width=0.4,color="black",URL="$classmcl__periodic__proc.html"]; + Node9 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="findadu_cache\nlastadu_cache",fontname="Helvetica"]; + Node19 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="sig_tab\npsig_next",fontname="Helvetica"]; + Node19 [label="sig_tab",height=0.2,width=0.4,color="black",URL="$structsig__tab.html"]; + Node5 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="saddr",fontname="Helvetica"]; + Node19 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node5 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr\nmcast_if_addr\nsrc_addr",fontname="Helvetica"]; + Node20 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx",fontname="Helvetica"]; + Node20 [label="mcl_tx",height=0.2,width=0.4,color="black",URL="$classmcl__tx.html"]; + Node9 -> Node20 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_start\nadu_head\nadu_end",fontname="Helvetica"]; + Node21 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_storage",fontname="Helvetica"]; + Node21 [label="mcl_rx_storage",height=0.2,width=0.4,color="black",URL="$classmcl__rx__storage.html"]; + Node22 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="object_list_tail\nfindobject_cache\nobject_list_head",fontname="Helvetica"]; + Node22 [label="object",height=0.2,width=0.4,color="black",URL="$structobject.html"]; + Node7 -> Node22 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="first_du\nlast_decoded_du",fontname="Helvetica"]; + Node8 -> Node22 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="first_blk",fontname="Helvetica"]; + Node22 -> Node22 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/classmcl__meta__object__coll__graph.md5 b/doc/doxygen/alc/html/classmcl__meta__object__coll__graph.md5 new file mode 100644 index 0000000..bc23b3e --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__meta__object__coll__graph.md5 @@ -0,0 +1 @@ +408eb7d3c65872c34441cb4f68e3157c \ No newline at end of file diff --git a/doc/doxygen/alc/html/classmcl__meta__object__layer__coll__graph.dot b/doc/doxygen/alc/html/classmcl__meta__object__layer__coll__graph.dot new file mode 100644 index 0000000..43a15b2 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__meta__object__layer__coll__graph.dot @@ -0,0 +1,72 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_meta_object_layer",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="current_mo",fontname="Helvetica"]; + Node2 [label="mcl_meta_object",height=0.2,width=0.4,color="black",URL="$classmcl__meta__object.html"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="mclcb",fontname="Helvetica"]; + Node3 [label="mcl_cb",height=0.2,width=0.4,color="black",URL="$classmcl__cb.html"]; + Node4 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fsm",fontname="Helvetica"]; + Node4 [label="mcl_fsm",height=0.2,width=0.4,color="black",URL="$classmcl__fsm.html"]; + Node5 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket_tab",fontname="Helvetica"]; + Node5 [label="mcl_socket",height=0.2,width=0.4,color="black",URL="$classmcl__socket.html"]; + Node6 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node6 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node7 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rxlvl",fontname="Helvetica"]; + Node7 [label="rxlay_t",height=0.2,width=0.4,color="black",URL="$structrxlay__t.html"]; + Node8 -> Node7 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node8 [label="du",height=0.2,width=0.4,color="black",URL="$structdu.html"]; + Node8 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node9 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node9 [label="block",height=0.2,width=0.4,color="black",URL="$structblock.html"]; + Node8 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node10 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node10 [label="adu",height=0.2,width=0.4,color="black",URL="$structadu.html"]; + Node9 -> Node10 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node10 -> Node10 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node6 -> Node10 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node5 -> Node7 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket_head",fontname="Helvetica"]; + Node11 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_flute",fontname="Helvetica"]; + Node11 [label="mcl_rx_flute",height=0.2,width=0.4,color="black",URL="$classmcl__rx__flute.html"]; + Node12 -> Node11 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="desired_tois",fontname="Helvetica"]; + Node12 [label="mcl_toi_list",height=0.2,width=0.4,color="black",URL="$structmcl__toi__list.html"]; + Node12 -> Node12 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node13 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_window",fontname="Helvetica"]; + Node13 [label="mcl_rx_window",height=0.2,width=0.4,color="black",URL="$classmcl__rx__window.html"]; + Node10 -> Node13 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head\nnext_ordered_adu_to_return",fontname="Helvetica"]; + Node14 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_flute",fontname="Helvetica"]; + Node14 [label="mcl_tx_flute",height=0.2,width=0.4,color="black",URL="$classmcl__tx__flute.html"]; + Node15 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="txlay_tab",fontname="Helvetica"]; + Node15 [label="txlay",height=0.2,width=0.4,color="black",URL="$structtxlay.html"]; + Node5 -> Node15 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket",fontname="Helvetica"]; + Node16 -> Node15 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_tab\ntx_tab_high",fontname="Helvetica"]; + Node16 [label="mcl_tx_tab",height=0.2,width=0.4,color="red",URL="$classmcl__tx__tab.html"]; + Node17 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="stats",fontname="Helvetica"]; + Node17 [label="stats_t",height=0.2,width=0.4,color="black",URL="$structstats__t.html"]; + Node18 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fec",fontname="Helvetica"]; + Node18 [label="mcl_fec",height=0.2,width=0.4,color="black",URL="$classmcl__fec.html"]; + Node19 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="periodic_proc",fontname="Helvetica"]; + Node19 [label="mcl_periodic_proc",height=0.2,width=0.4,color="black",URL="$classmcl__periodic__proc.html"]; + Node10 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="findadu_cache\nlastadu_cache",fontname="Helvetica"]; + Node20 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="sig_tab\npsig_next",fontname="Helvetica"]; + Node20 [label="sig_tab",height=0.2,width=0.4,color="black",URL="$structsig__tab.html"]; + Node6 -> Node20 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="saddr",fontname="Helvetica"]; + Node20 -> Node20 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node6 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr\nmcast_if_addr\nsrc_addr",fontname="Helvetica"]; + Node21 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx",fontname="Helvetica"]; + Node21 [label="mcl_tx",height=0.2,width=0.4,color="black",URL="$classmcl__tx.html"]; + Node10 -> Node21 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_start\nadu_head\nadu_end",fontname="Helvetica"]; + Node22 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_storage",fontname="Helvetica"]; + Node22 [label="mcl_rx_storage",height=0.2,width=0.4,color="black",URL="$classmcl__rx__storage.html"]; + Node23 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="object_list_tail\nfindobject_cache\nobject_list_head",fontname="Helvetica"]; + Node23 [label="object",height=0.2,width=0.4,color="black",URL="$structobject.html"]; + Node8 -> Node23 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="first_du\nlast_decoded_du",fontname="Helvetica"]; + Node9 -> Node23 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="first_blk",fontname="Helvetica"]; + Node23 -> Node23 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node3 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="mclcb",fontname="Helvetica"]; + Node24 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="meta_object_list",fontname="Helvetica"]; + Node24 [label="list_of_meta_objects",height=0.2,width=0.4,color="black",URL="$structlist__of__meta__objects.html"]; + Node2 -> Node24 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="meta_obj",fontname="Helvetica"]; + Node24 -> Node24 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/classmcl__meta__object__layer__coll__graph.md5 b/doc/doxygen/alc/html/classmcl__meta__object__layer__coll__graph.md5 new file mode 100644 index 0000000..603d9d8 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__meta__object__layer__coll__graph.md5 @@ -0,0 +1 @@ +18aba33a142a47fcd94af92c9c2a9667 \ No newline at end of file diff --git a/doc/doxygen/alc/html/classmcl__rx__flute__coll__graph.dot b/doc/doxygen/alc/html/classmcl__rx__flute__coll__graph.dot new file mode 100644 index 0000000..4d8f2d8 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__rx__flute__coll__graph.dot @@ -0,0 +1,9 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_rx_flute",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="desired_tois",fontname="Helvetica"]; + Node2 [label="mcl_toi_list",height=0.2,width=0.4,color="black",URL="$structmcl__toi__list.html"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/classmcl__rx__flute__coll__graph.md5 b/doc/doxygen/alc/html/classmcl__rx__flute__coll__graph.md5 new file mode 100644 index 0000000..ebfa3c7 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__rx__flute__coll__graph.md5 @@ -0,0 +1 @@ +da2f1d530baaa81fcd86eda5d6409cdb \ No newline at end of file diff --git a/doc/doxygen/alc/html/classmcl__rx__window__coll__graph.dot b/doc/doxygen/alc/html/classmcl__rx__window__coll__graph.dot new file mode 100644 index 0000000..ce580d1 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__rx__window__coll__graph.dot @@ -0,0 +1,16 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_rx_window",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head\nnext_ordered_adu_to_return",fontname="Helvetica"]; + Node2 [label="adu",height=0.2,width=0.4,color="black",URL="$structadu.html"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="blocking_struct",fontname="Helvetica"]; + Node3 [label="mcl_blocking_struct",height=0.2,width=0.4,color="black",URL="$structmcl__blocking__struct.html"]; + Node4 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node4 [label="block",height=0.2,width=0.4,color="red",URL="$structblock.html"]; + Node2 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node5 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node5 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; +} diff --git a/doc/doxygen/alc/html/classmcl__rx__window__coll__graph.md5 b/doc/doxygen/alc/html/classmcl__rx__window__coll__graph.md5 new file mode 100644 index 0000000..7497197 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__rx__window__coll__graph.md5 @@ -0,0 +1 @@ +4d56c4974ef384c1183cc7e8dea1378c \ No newline at end of file diff --git a/doc/doxygen/alc/html/classmcl__socket__coll__graph.dot b/doc/doxygen/alc/html/classmcl__socket__coll__graph.dot new file mode 100644 index 0000000..896ea30 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__socket__coll__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_socket",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node2 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; +} diff --git a/doc/doxygen/alc/html/classmcl__socket__coll__graph.md5 b/doc/doxygen/alc/html/classmcl__socket__coll__graph.md5 new file mode 100644 index 0000000..b626123 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__socket__coll__graph.md5 @@ -0,0 +1 @@ +419ffb8e30e9ad2693df376fed300073 \ No newline at end of file diff --git a/doc/doxygen/alc/html/classmcl__tx__coll__graph.dot b/doc/doxygen/alc/html/classmcl__tx__coll__graph.dot new file mode 100644 index 0000000..39e3365 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__tx__coll__graph.dot @@ -0,0 +1,16 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_tx",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_start\nadu_head\nadu_end",fontname="Helvetica"]; + Node2 [label="adu",height=0.2,width=0.4,color="black",URL="$structadu.html"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="blocking_struct",fontname="Helvetica"]; + Node3 [label="mcl_blocking_struct",height=0.2,width=0.4,color="black",URL="$structmcl__blocking__struct.html"]; + Node4 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node4 [label="block",height=0.2,width=0.4,color="red",URL="$structblock.html"]; + Node2 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node5 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node5 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; +} diff --git a/doc/doxygen/alc/html/classmcl__tx__coll__graph.md5 b/doc/doxygen/alc/html/classmcl__tx__coll__graph.md5 new file mode 100644 index 0000000..a46e5f6 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__tx__coll__graph.md5 @@ -0,0 +1 @@ +704afb6d828248fe80b30c266e2b59fc \ No newline at end of file diff --git a/doc/doxygen/alc/html/classmcl__tx__tab__coll__graph.dot b/doc/doxygen/alc/html/classmcl__tx__tab__coll__graph.dot new file mode 100644 index 0000000..b7cd367 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__tx__tab__coll__graph.dot @@ -0,0 +1,17 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_tx_tab",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="cached_txtab\ntxtab_head",fontname="Helvetica"]; + Node2 [label="txtab",height=0.2,width=0.4,color="black",URL="$structtxtab.html"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_tab",fontname="Helvetica"]; + Node3 [label="du",height=0.2,width=0.4,color="black",URL="$structdu.html"]; + Node3 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node4 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="pkt",fontname="Helvetica"]; + Node4 [label="mcl_rx_pkt",height=0.2,width=0.4,color="black",URL="$classmcl__rx__pkt.html"]; + Node5 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node5 [label="block",height=0.2,width=0.4,color="red",URL="$structblock.html"]; + Node3 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/classmcl__tx__tab__coll__graph.md5 b/doc/doxygen/alc/html/classmcl__tx__tab__coll__graph.md5 new file mode 100644 index 0000000..6d5e117 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__tx__tab__coll__graph.md5 @@ -0,0 +1 @@ +9fa2cf946c2ae12ba97863d200c61b9a \ No newline at end of file diff --git a/doc/doxygen/alc/html/classmcl__tx__window__coll__graph.dot b/doc/doxygen/alc/html/classmcl__tx__window__coll__graph.dot new file mode 100644 index 0000000..8e9a6a8 --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__tx__window__coll__graph.dot @@ -0,0 +1,16 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_tx_window",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head\nnext_ordered_adu_to_return",fontname="Helvetica"]; + Node2 [label="adu",height=0.2,width=0.4,color="black",URL="$structadu.html"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="blocking_struct",fontname="Helvetica"]; + Node3 [label="mcl_blocking_struct",height=0.2,width=0.4,color="black",URL="$structmcl__blocking__struct.html"]; + Node4 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node4 [label="block",height=0.2,width=0.4,color="red",URL="$structblock.html"]; + Node2 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node5 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node5 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; +} diff --git a/doc/doxygen/alc/html/classmcl__tx__window__coll__graph.md5 b/doc/doxygen/alc/html/classmcl__tx__window__coll__graph.md5 new file mode 100644 index 0000000..e0d1e5e --- /dev/null +++ b/doc/doxygen/alc/html/classmcl__tx__window__coll__graph.md5 @@ -0,0 +1 @@ +aacd183f0ca280c961faf1713ddee586 \ No newline at end of file diff --git a/doc/doxygen/alc/html/doxygen.css b/doc/doxygen/alc/html/doxygen.css new file mode 100644 index 0000000..1d4d631 --- /dev/null +++ b/doc/doxygen/alc/html/doxygen.css @@ -0,0 +1,271 @@ +BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +H1 { + text-align: center; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #eeeeff; + border: 1px solid #b0b0b0; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +DIV.nav { + width: 100%; + background-color: #eeeeff; + border: 1px solid #b0b0b0; + text-align: center; + margin: 2px; + padding: 2px; + line-height: 140%; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + border: 1px double #9295C2; +} +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code:link { text-decoration: none; font-weight: normal; color: #0000FF} +A.code:visited { text-decoration: none; font-weight: normal; color: #0000FF} +A.codeRef:link { font-weight: normal; color: #0000FF} +A.codeRef:visited { font-weight: normal; color: #0000FF} +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +.fragment { + font-family: monospace +} +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } +TD.md { background-color: #F4F4FB; font-weight: bold; } +TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; } +TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; } +DIV.groupHeader { + margin-left: 16px; + margin-top: 12px; + margin-bottom: 6px; + font-weight: bold; +} +DIV.groupText { margin-left: 16px; font-style: italic; font-size: 14px } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #eeeeff; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #eeeeff; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdTable { + border: 1px solid #868686; + background-color: #F4F4FB; +} +.mdRow { + padding: 8px 10px; +} +.mdescLeft { + padding: 0px 8px 4px 8px; + font-size: 12px; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + padding: 0px 8px 4px 8px; + font-size: 12px; + font-style: italic; + background-color: #FAFAFA; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 12px; +} +.memItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 13px; +} +.memTemplItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 12px; +} +.memTemplItemRight { + padding: 1px 8px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: none; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-size: 13px; +} +.memTemplParams { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-top-style: solid; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + color: #606060; + background-color: #FAFAFA; + font-size: 12px; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #eeeeff; +} +TD.tiny { font-size: 75%; +} +a { + color: #252E78; +} +a:visited { + color: #3D2185; +} diff --git a/doc/doxygen/alc/html/doxygen.png b/doc/doxygen/alc/html/doxygen.png new file mode 100644 index 0000000..f0a274b Binary files /dev/null and b/doc/doxygen/alc/html/doxygen.png differ diff --git a/doc/doxygen/alc/html/graph_legend.dot b/doc/doxygen/alc/html/graph_legend.dot new file mode 100644 index 0000000..5420927 --- /dev/null +++ b/doc/doxygen/alc/html/graph_legend.dot @@ -0,0 +1,22 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node9 [shape="box",label="Inherited",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",style="filled" fontcolor="white"]; + Node10 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [shape="box",label="PublicBase",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classPublicBase.html"]; + Node11 -> Node10 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [shape="box",label="Truncated",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="red",URL="$classTruncated.html"]; + Node13 -> Node9 [dir=back,color="darkgreen",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [shape="box",label="ProtectedBase",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classProtectedBase.html"]; + Node14 -> Node9 [dir=back,color="firebrick4",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [shape="box",label="PrivateBase",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classPrivateBase.html"]; + Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [shape="box",label="Undocumented",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="grey75"]; + Node16 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [shape="box",label="Templ< int >",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classTempl.html"]; + Node17 -> Node16 [dir=back,color="orange",fontsize=10,style="dashed",label="< int >",fontname="Helvetica"]; + Node17 [shape="box",label="Templ< T >",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classTempl.html"]; + Node18 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="m_usedClass",fontname="Helvetica"]; + Node18 [shape="box",label="Used",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classUsed.html"]; +} diff --git a/doc/doxygen/alc/html/mcl_8cpp__incl.dot b/doc/doxygen/alc/html/mcl_8cpp__incl.dot new file mode 100644 index 0000000..fe4604d --- /dev/null +++ b/doc/doxygen/alc/html/mcl_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl_8cpp__incl.md5 new file mode 100644 index 0000000..56900f0 --- /dev/null +++ b/doc/doxygen/alc/html/mcl_8cpp__incl.md5 @@ -0,0 +1 @@ +44fec85e1fccd51d0e718d207878f5b9 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl_8h__dep__incl.dot new file mode 100644 index 0000000..78435be --- /dev/null +++ b/doc/doxygen/alc/html/mcl_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl_8h__dep__incl.md5 new file mode 100644 index 0000000..babc262 --- /dev/null +++ b/doc/doxygen/alc/html/mcl_8h__dep__incl.md5 @@ -0,0 +1 @@ +5a357b36f2a47ab610041ddd31990ee7 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__addr_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__addr_8h__dep__incl.dot new file mode 100644 index 0000000..ee446f2 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__addr_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_addr.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__addr_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__addr_8h__dep__incl.md5 new file mode 100644 index 0000000..bcb5b16 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__addr_8h__dep__incl.md5 @@ -0,0 +1 @@ +75790d2f9fb0081ec41b8ed7e3a15fa1 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__adu_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__adu_8cpp__incl.dot new file mode 100644 index 0000000..7461cbf --- /dev/null +++ b/doc/doxygen/alc/html/mcl__adu_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_adu.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__adu_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__adu_8cpp__incl.md5 new file mode 100644 index 0000000..8d58705 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__adu_8cpp__incl.md5 @@ -0,0 +1 @@ +b79e3155cead490a72dde020a5df37d5 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__alc__hdr_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__alc__hdr_8cpp__incl.dot new file mode 100644 index 0000000..de7b0ba --- /dev/null +++ b/doc/doxygen/alc/html/mcl__alc__hdr_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_alc_hdr.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__alc__hdr_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__alc__hdr_8cpp__incl.md5 new file mode 100644 index 0000000..e4164f9 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__alc__hdr_8cpp__incl.md5 @@ -0,0 +1 @@ +986bd688b3f90caf280cebc8347fc74c \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__alc__hdr_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__alc__hdr_8h__dep__incl.dot new file mode 100644 index 0000000..cf75d42 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__alc__hdr_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__alc__hdr_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__alc__hdr_8h__dep__incl.md5 new file mode 100644 index 0000000..555319d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__alc__hdr_8h__dep__incl.md5 @@ -0,0 +1 @@ +afb7c0b9556148d825f1aab12fc5e60c \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__blocking__struct_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__blocking__struct_8h__dep__incl.dot new file mode 100644 index 0000000..744a89c --- /dev/null +++ b/doc/doxygen/alc/html/mcl__blocking__struct_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_blocking_struct.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__blocking__struct_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__blocking__struct_8h__dep__incl.md5 new file mode 100644 index 0000000..6bd27bb --- /dev/null +++ b/doc/doxygen/alc/html/mcl__blocking__struct_8h__dep__incl.md5 @@ -0,0 +1 @@ +d722b8a88453f73400535cfb5b509840 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__cb_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__cb_8cpp__incl.dot new file mode 100644 index 0000000..c4cec83 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__cb_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_cb.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__cb_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__cb_8cpp__incl.md5 new file mode 100644 index 0000000..006db6f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__cb_8cpp__incl.md5 @@ -0,0 +1 @@ +522422eca1327148ad545c0fc16e6b62 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__cb_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__cb_8h__dep__incl.dot new file mode 100644 index 0000000..1ab261d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__cb_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_cb.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__cb_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__cb_8h__dep__incl.md5 new file mode 100644 index 0000000..8e338bd --- /dev/null +++ b/doc/doxygen/alc/html/mcl__cb_8h__dep__incl.md5 @@ -0,0 +1 @@ +b4f66186adad43aeaec916e791719390 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__cb_8h__incl.dot b/doc/doxygen/alc/html/mcl__cb_8h__incl.dot new file mode 100644 index 0000000..5d3b59f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__cb_8h__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_cb.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__cb_8h__incl.md5 b/doc/doxygen/alc/html/mcl__cb_8h__incl.md5 new file mode 100644 index 0000000..3796b2d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__cb_8h__incl.md5 @@ -0,0 +1 @@ +139979b00d12304758ba07dd0d7b3605 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__data_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__data_8h__dep__incl.dot new file mode 100644 index 0000000..5b10f8d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__data_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_data.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__data_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__data_8h__dep__incl.md5 new file mode 100644 index 0000000..102099f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__data_8h__dep__incl.md5 @@ -0,0 +1 @@ +95b25f4a8557ed90bb22aa2936330afe \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__data_8h__incl.dot b/doc/doxygen/alc/html/mcl__data_8h__incl.dot new file mode 100644 index 0000000..ff965e7 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__data_8h__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_data.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__data_8h__incl.md5 b/doc/doxygen/alc/html/mcl__data_8h__incl.md5 new file mode 100644 index 0000000..2d2813c --- /dev/null +++ b/doc/doxygen/alc/html/mcl__data_8h__incl.md5 @@ -0,0 +1 @@ +f28a0d4b2c41e2df11c9808637f20303 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__debug_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__debug_8h__dep__incl.dot new file mode 100644 index 0000000..239d90e --- /dev/null +++ b/doc/doxygen/alc/html/mcl__debug_8h__dep__incl.dot @@ -0,0 +1,10 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_debug.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; + Node3 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="rse_fec.cpp",height=0.2,width=0.4,color="black",URL="$rse__fec_8cpp.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__debug_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__debug_8h__dep__incl.md5 new file mode 100644 index 0000000..3736ceb --- /dev/null +++ b/doc/doxygen/alc/html/mcl__debug_8h__dep__incl.md5 @@ -0,0 +1 @@ +741dccbaf403a65ff329eeabb03c394c \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__defines_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__defines_8h__dep__incl.dot new file mode 100644 index 0000000..4d32288 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__defines_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_defines.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__defines_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__defines_8h__dep__incl.md5 new file mode 100644 index 0000000..63abf9f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__defines_8h__dep__incl.md5 @@ -0,0 +1 @@ +332b525ad229d35fc89ef2410e44ecf0 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__du_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__du_8cpp__incl.dot new file mode 100644 index 0000000..2c713dd --- /dev/null +++ b/doc/doxygen/alc/html/mcl__du_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_du.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__du_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__du_8cpp__incl.md5 new file mode 100644 index 0000000..55d7e95 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__du_8cpp__incl.md5 @@ -0,0 +1 @@ +0c7ef3eddbe000c7f496485b1713d803 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__error_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__error_8h__dep__incl.dot new file mode 100644 index 0000000..52c2c2e --- /dev/null +++ b/doc/doxygen/alc/html/mcl__error_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_error.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__error_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__error_8h__dep__incl.md5 new file mode 100644 index 0000000..f6d7569 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__error_8h__dep__incl.md5 @@ -0,0 +1 @@ +c79ef317773c7081d3bc84bb59e2c567 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__fec_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__fec_8cpp__incl.dot new file mode 100644 index 0000000..1f70a92 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__fec_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_fec.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__fec_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__fec_8cpp__incl.md5 new file mode 100644 index 0000000..0700310 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__fec_8cpp__incl.md5 @@ -0,0 +1 @@ +ffa5423dccfb62e427c86be5b44b80a2 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__fec_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__fec_8h__dep__incl.dot new file mode 100644 index 0000000..f9fedb1 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__fec_8h__dep__incl.dot @@ -0,0 +1,11 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_fec.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node3 -> Node2 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/mcl__fec_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__fec_8h__dep__incl.md5 new file mode 100644 index 0000000..d09ae78 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__fec_8h__dep__incl.md5 @@ -0,0 +1 @@ +c00daa9fa09af4fe580da903da4c177c \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__file__io_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__file__io_8h__dep__incl.dot new file mode 100644 index 0000000..eff166d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__file__io_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_file_io.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__file__io_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__file__io_8h__dep__incl.md5 new file mode 100644 index 0000000..fcd1457 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__file__io_8h__dep__incl.md5 @@ -0,0 +1 @@ +2e3d78f35ec2642242a5d993eaed1326 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__flid__sl_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__flid__sl_8cpp__incl.dot new file mode 100644 index 0000000..e41bacb --- /dev/null +++ b/doc/doxygen/alc/html/mcl__flid__sl_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_flid_sl.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__flid__sl_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__flid__sl_8cpp__incl.md5 new file mode 100644 index 0000000..5b48994 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__flid__sl_8cpp__incl.md5 @@ -0,0 +1 @@ +c40da821676e55d17882143b70ae63f8 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__flid__sl_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__flid__sl_8h__dep__incl.dot new file mode 100644 index 0000000..85086aa --- /dev/null +++ b/doc/doxygen/alc/html/mcl__flid__sl_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__flid__sl_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__flid__sl_8h__dep__incl.md5 new file mode 100644 index 0000000..810b5e1 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__flid__sl_8h__dep__incl.md5 @@ -0,0 +1 @@ +529c230f848f7eef119b3f2275cdb42c \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__flute_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__flute_8cpp__incl.dot new file mode 100644 index 0000000..88e5f19 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__flute_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_flute.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__flute_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__flute_8cpp__incl.md5 new file mode 100644 index 0000000..061bb73 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__flute_8cpp__incl.md5 @@ -0,0 +1 @@ +765d423ae74de0b94b97a0b9278604bd \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__flute_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__flute_8h__dep__incl.dot new file mode 100644 index 0000000..a434403 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__flute_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_flute.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__flute_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__flute_8h__dep__incl.md5 new file mode 100644 index 0000000..10ac6e1 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__flute_8h__dep__incl.md5 @@ -0,0 +1 @@ +0bea73869fe40cab9fdc9cce67688e28 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__fsm_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__fsm_8cpp__incl.dot new file mode 100644 index 0000000..9f30f5f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__fsm_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_fsm.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__fsm_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__fsm_8cpp__incl.md5 new file mode 100644 index 0000000..47e9bd8 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__fsm_8cpp__incl.md5 @@ -0,0 +1 @@ +e9fc043b7282a8628ea7ef1f4e45b463 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__fsm_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__fsm_8h__dep__incl.dot new file mode 100644 index 0000000..7db77bb --- /dev/null +++ b/doc/doxygen/alc/html/mcl__fsm_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_fsm.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__fsm_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__fsm_8h__dep__incl.md5 new file mode 100644 index 0000000..1e9da0f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__fsm_8h__dep__incl.md5 @@ -0,0 +1 @@ +0ce7d1c9b456a6661959100585621862 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__includes_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__includes_8h__dep__incl.dot new file mode 100644 index 0000000..9f3367f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__includes_8h__dep__incl.dot @@ -0,0 +1,64 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_includes.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl.cpp",height=0.2,width=0.4,color="black",URL="$mcl_8cpp.html"]; + Node3 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="mcl_adu.cpp",height=0.2,width=0.4,color="black",URL="$mcl__adu_8cpp.html"]; + Node4 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="mcl_alc_hdr.cpp",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8cpp.html"]; + Node5 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="mcl_cb.cpp",height=0.2,width=0.4,color="black",URL="$mcl__cb_8cpp.html"]; + Node6 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="mcl_du.cpp",height=0.2,width=0.4,color="black",URL="$mcl__du_8cpp.html"]; + Node7 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="mcl_fec.cpp",height=0.2,width=0.4,color="black",URL="$mcl__fec_8cpp.html"]; + Node8 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="mcl_flid_sl.cpp",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8cpp.html"]; + Node9 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="mcl_flute.cpp",height=0.2,width=0.4,color="black",URL="$mcl__flute_8cpp.html"]; + Node10 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="mcl_fsm.cpp",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8cpp.html"]; + Node11 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="mcl_layer.cpp",height=0.2,width=0.4,color="black",URL="$mcl__layer_8cpp.html"]; + Node12 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="mcl_lct_hdr.cpp",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8cpp.html"]; + Node13 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="mcl_lib.cpp",height=0.2,width=0.4,color="black",URL="$mcl__lib_8cpp.html"]; + Node14 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="mcl_meta_object.cpp",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8cpp.html"]; + Node15 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="mcl_meta_object_layer.cpp",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8cpp.html"]; + Node16 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="mcl_network.cpp",height=0.2,width=0.4,color="black",URL="$mcl__network_8cpp.html"]; + Node17 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="mcl_periodic_proc.cpp",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8cpp.html"]; + Node18 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="mcl_rlc.cpp",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8cpp.html"]; + Node19 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="mcl_rx.cpp",height=0.2,width=0.4,color="black",URL="$mcl__rx_8cpp.html"]; + Node20 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="mcl_rx_storage.cpp",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8cpp.html"]; + Node21 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="mcl_rx_window.cpp",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8cpp.html"]; + Node22 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="mcl_sched.cpp",height=0.2,width=0.4,color="black",URL="$mcl__sched_8cpp.html"]; + Node23 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="mcl_sig.cpp",height=0.2,width=0.4,color="black",URL="$mcl__sig_8cpp.html"]; + Node24 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="mcl_socket.cpp",height=0.2,width=0.4,color="black",URL="$mcl__socket_8cpp.html"]; + Node25 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="mcl_stats.cpp",height=0.2,width=0.4,color="black",URL="$mcl__stats_8cpp.html"]; + Node26 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="mcl_tx.cpp",height=0.2,width=0.4,color="black",URL="$mcl__tx_8cpp.html"]; + Node27 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="mcl_tx_prof.cpp",height=0.2,width=0.4,color="black",URL="$mcl__tx__prof_8cpp.html"]; + Node28 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="mcl_tx_tab.cpp",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8cpp.html"]; + Node29 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="mcl_vrmem.cpp",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8cpp.html"]; + Node30 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="mcl_vtmem.cpp",height=0.2,width=0.4,color="black",URL="$mcl__vtmem_8cpp.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__includes_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__includes_8h__dep__incl.md5 new file mode 100644 index 0000000..ea8bb21 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__includes_8h__dep__incl.md5 @@ -0,0 +1 @@ +4a4da82dc8a740c54741bfc9d2fb2888 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__includes_8h__incl.dot b/doc/doxygen/alc/html/mcl__includes_8h__incl.dot new file mode 100644 index 0000000..02269df --- /dev/null +++ b/doc/doxygen/alc/html/mcl__includes_8h__incl.dot @@ -0,0 +1,139 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_includes.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node3 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="new",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node31 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node32 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node33 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node34 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node30 -> Node34 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node36 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node37 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node38 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node39 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node40 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node41 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node42 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node43 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node44 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node45 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node46 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node47 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node48 -> Node47 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node48 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node50 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node51 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node52 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node53 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node54 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node55 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node56 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node57 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node58 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node59 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node60 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node61 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node62 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node63 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node64 -> Node63 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node64 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node66 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__includes_8h__incl.md5 b/doc/doxygen/alc/html/mcl__includes_8h__incl.md5 new file mode 100644 index 0000000..1be5f02 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__includes_8h__incl.md5 @@ -0,0 +1 @@ +2fa8fb12c976975573b59e9eaf4a3765 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__itime_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__itime_8h__dep__incl.dot new file mode 100644 index 0000000..f1e2139 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__itime_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_itime.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__itime_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__itime_8h__dep__incl.md5 new file mode 100644 index 0000000..acec91b --- /dev/null +++ b/doc/doxygen/alc/html/mcl__itime_8h__dep__incl.md5 @@ -0,0 +1 @@ +4abe75a9cde6c512980a489bd4ab4ab8 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__layer_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__layer_8cpp__incl.dot new file mode 100644 index 0000000..2ef142c --- /dev/null +++ b/doc/doxygen/alc/html/mcl__layer_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_layer.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__layer_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__layer_8cpp__incl.md5 new file mode 100644 index 0000000..96f6794 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__layer_8cpp__incl.md5 @@ -0,0 +1 @@ +b1399fccf451cb203ec53c7b9a1263ec \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__lct__hdr_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__lct__hdr_8cpp__incl.dot new file mode 100644 index 0000000..8cae062 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lct__hdr_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_lct_hdr.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__lct__hdr_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__lct__hdr_8cpp__incl.md5 new file mode 100644 index 0000000..99fcb77 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lct__hdr_8cpp__incl.md5 @@ -0,0 +1 @@ +a4e35ac0a4a4b561f68f53d1b740286a \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__lct__hdr_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__lct__hdr_8h__dep__incl.dot new file mode 100644 index 0000000..e83af11 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lct__hdr_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__lct__hdr_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__lct__hdr_8h__dep__incl.md5 new file mode 100644 index 0000000..7404c67 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lct__hdr_8h__dep__incl.md5 @@ -0,0 +1 @@ +e717bdcec32bba044c0e559edc18d435 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__lib_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__lib_8cpp__incl.dot new file mode 100644 index 0000000..18001d5 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_lib.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__lib_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__lib_8cpp__incl.md5 new file mode 100644 index 0000000..b5cdec9 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib_8cpp__incl.md5 @@ -0,0 +1 @@ +6d9537d20ab8a91727aa05e4b8137484 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__lib_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__lib_8h__dep__incl.dot new file mode 100644 index 0000000..c77969d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_lib.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__lib_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__lib_8h__dep__incl.md5 new file mode 100644 index 0000000..3a747cb --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib_8h__dep__incl.md5 @@ -0,0 +1 @@ +9618d1cf76eda7c8f5ce61416f130a39 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__lib__api_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__lib__api_8h__dep__incl.dot new file mode 100644 index 0000000..37aa850 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib__api_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_lib_api.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__lib__api_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__lib__api_8h__dep__incl.md5 new file mode 100644 index 0000000..355bfcb --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib__api_8h__dep__incl.md5 @@ -0,0 +1 @@ +512293f0c2c492c66569246a499737fd \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__lib__api_8h__incl.dot b/doc/doxygen/alc/html/mcl__lib__api_8h__incl.dot new file mode 100644 index 0000000..ecd8d2f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib__api_8h__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_lib_api.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__lib__api_8h__incl.md5 b/doc/doxygen/alc/html/mcl__lib__api_8h__incl.md5 new file mode 100644 index 0000000..ed3d83b --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib__api_8h__incl.md5 @@ -0,0 +1 @@ +5efd16e290dd7b26ea6c43a9303a168b \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__lib__api__alc_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__lib__api__alc_8h__dep__incl.dot new file mode 100644 index 0000000..e91ee4a --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib__api__alc_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_lib_api_alc.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__lib__api__alc_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__lib__api__alc_8h__dep__incl.md5 new file mode 100644 index 0000000..e4b1a9d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__lib__api__alc_8h__dep__incl.md5 @@ -0,0 +1 @@ +ab9617a8461f9edee73962fba2064728 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__meta__object_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__meta__object_8cpp__incl.dot new file mode 100644 index 0000000..8c43f76 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__meta__object_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_meta_object.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__meta__object_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__meta__object_8cpp__incl.md5 new file mode 100644 index 0000000..c0f047a --- /dev/null +++ b/doc/doxygen/alc/html/mcl__meta__object_8cpp__incl.md5 @@ -0,0 +1 @@ +e2a89095be02f97188ffa220cca21ec7 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__meta__object_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__meta__object_8h__dep__incl.dot new file mode 100644 index 0000000..5d256ab --- /dev/null +++ b/doc/doxygen/alc/html/mcl__meta__object_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_meta_object.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__meta__object_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__meta__object_8h__dep__incl.md5 new file mode 100644 index 0000000..37240f6 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__meta__object_8h__dep__incl.md5 @@ -0,0 +1 @@ +0b6415c5b6bd0be6c5eaeb36b8a6b9fd \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__meta__object__layer_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__meta__object__layer_8cpp__incl.dot new file mode 100644 index 0000000..a46e254 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__meta__object__layer_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_meta_object_layer.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__meta__object__layer_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__meta__object__layer_8cpp__incl.md5 new file mode 100644 index 0000000..e071914 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__meta__object__layer_8cpp__incl.md5 @@ -0,0 +1 @@ +e4bf6eee0fc02d9701f5dadbdd468a67 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__meta__object__layer_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__meta__object__layer_8h__dep__incl.dot new file mode 100644 index 0000000..b2daf6e --- /dev/null +++ b/doc/doxygen/alc/html/mcl__meta__object__layer_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__meta__object__layer_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__meta__object__layer_8h__dep__incl.md5 new file mode 100644 index 0000000..1c3a4fb --- /dev/null +++ b/doc/doxygen/alc/html/mcl__meta__object__layer_8h__dep__incl.md5 @@ -0,0 +1 @@ +753615572ac4b5e33b17572cc35fedef \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__network_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__network_8cpp__incl.dot new file mode 100644 index 0000000..f414fed --- /dev/null +++ b/doc/doxygen/alc/html/mcl__network_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_network.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__network_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__network_8cpp__incl.md5 new file mode 100644 index 0000000..7986f14 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__network_8cpp__incl.md5 @@ -0,0 +1 @@ +18a230e45b08b46a7cb146574b6179ff \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__osdep_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__osdep_8h__dep__incl.dot new file mode 100644 index 0000000..7418340 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__osdep_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_osdep.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__osdep_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__osdep_8h__dep__incl.md5 new file mode 100644 index 0000000..cdb63ef --- /dev/null +++ b/doc/doxygen/alc/html/mcl__osdep_8h__dep__incl.md5 @@ -0,0 +1 @@ +d865cd19048837e18a096ad95ac0950c \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__periodic__proc_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__periodic__proc_8cpp__incl.dot new file mode 100644 index 0000000..734962f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__periodic__proc_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_periodic_proc.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__periodic__proc_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__periodic__proc_8cpp__incl.md5 new file mode 100644 index 0000000..4fffd82 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__periodic__proc_8cpp__incl.md5 @@ -0,0 +1 @@ +2eed66763f1c5d32a190bb6bc3a65255 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__periodic__proc_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__periodic__proc_8h__dep__incl.dot new file mode 100644 index 0000000..72d45c8 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__periodic__proc_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__periodic__proc_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__periodic__proc_8h__dep__incl.md5 new file mode 100644 index 0000000..ca95689 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__periodic__proc_8h__dep__incl.md5 @@ -0,0 +1 @@ +ce04f53d9bbed87bc6e0f6099ff61f64 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__periodic__timer_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__periodic__timer_8h__dep__incl.dot new file mode 100644 index 0000000..a62aa41 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__periodic__timer_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_periodic_timer.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__periodic__timer_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__periodic__timer_8h__dep__incl.md5 new file mode 100644 index 0000000..9d95046 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__periodic__timer_8h__dep__incl.md5 @@ -0,0 +1 @@ +2b4eb9ce5e4fea0c3a0913a2813e5a61 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__profile_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__profile_8h__dep__incl.dot new file mode 100644 index 0000000..7ea2209 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__profile_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_profile.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__profile_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__profile_8h__dep__incl.md5 new file mode 100644 index 0000000..a06fbed --- /dev/null +++ b/doc/doxygen/alc/html/mcl__profile_8h__dep__incl.md5 @@ -0,0 +1 @@ +9ae3ef7a0fe7f2f5bf1d9a85285c0d67 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__proto_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__proto_8h__dep__incl.dot new file mode 100644 index 0000000..4858e1d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__proto_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_proto.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__proto_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__proto_8h__dep__incl.md5 new file mode 100644 index 0000000..32ec898 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__proto_8h__dep__incl.md5 @@ -0,0 +1 @@ +b97c43bedcd2c62b5c2776c14f14ac83 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__rlc_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__rlc_8cpp__incl.dot new file mode 100644 index 0000000..e03b8b5 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rlc_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_rlc.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__rlc_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__rlc_8cpp__incl.md5 new file mode 100644 index 0000000..6cdcb54 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rlc_8cpp__incl.md5 @@ -0,0 +1 @@ +8ee4cf6a6eb5942944680be878f42d25 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__rlc_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__rlc_8h__dep__incl.dot new file mode 100644 index 0000000..1da3911 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rlc_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_rlc.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__rlc_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__rlc_8h__dep__incl.md5 new file mode 100644 index 0000000..af68c43 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rlc_8h__dep__incl.md5 @@ -0,0 +1 @@ +d2f4c6d2406a14da5c78f83a091fb749 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__rx_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__rx_8cpp__incl.dot new file mode 100644 index 0000000..cfc130e --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_rx.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__rx_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__rx_8cpp__incl.md5 new file mode 100644 index 0000000..c1b277d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx_8cpp__incl.md5 @@ -0,0 +1 @@ +96065d6bc7556fa0cf1ad737e0e26873 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__rx__storage_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__rx__storage_8cpp__incl.dot new file mode 100644 index 0000000..3693c3b --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx__storage_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_rx_storage.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__rx__storage_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__rx__storage_8cpp__incl.md5 new file mode 100644 index 0000000..ac83706 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx__storage_8cpp__incl.md5 @@ -0,0 +1 @@ +8e8b8333b40d3b40b375f360359bd356 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__rx__storage_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__rx__storage_8h__dep__incl.dot new file mode 100644 index 0000000..fb63684 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx__storage_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__rx__storage_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__rx__storage_8h__dep__incl.md5 new file mode 100644 index 0000000..709e0d7 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx__storage_8h__dep__incl.md5 @@ -0,0 +1 @@ +eeec10e7078d847fe6c257f953293440 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__rx__window_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__rx__window_8cpp__incl.dot new file mode 100644 index 0000000..b4979c6 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx__window_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_rx_window.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__rx__window_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__rx__window_8cpp__incl.md5 new file mode 100644 index 0000000..827e20d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx__window_8cpp__incl.md5 @@ -0,0 +1 @@ +ab0a39b107afbb7fe35e5f3efebacdbb \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__rx__window_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__rx__window_8h__dep__incl.dot new file mode 100644 index 0000000..3d62d18 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx__window_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_rx_window.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__rx__window_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__rx__window_8h__dep__incl.md5 new file mode 100644 index 0000000..4e31023 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__rx__window_8h__dep__incl.md5 @@ -0,0 +1 @@ +44a21a9feb161832e819895a66ad7e72 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__sched_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__sched_8cpp__incl.dot new file mode 100644 index 0000000..255c511 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__sched_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_sched.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__sched_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__sched_8cpp__incl.md5 new file mode 100644 index 0000000..0d9f8a1 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__sched_8cpp__incl.md5 @@ -0,0 +1 @@ +9da858148c80cb47e3b7c043f3babf11 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__sig_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__sig_8cpp__incl.dot new file mode 100644 index 0000000..5628fc2 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__sig_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_sig.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__sig_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__sig_8cpp__incl.md5 new file mode 100644 index 0000000..a1c46f9 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__sig_8cpp__incl.md5 @@ -0,0 +1 @@ +65d85a5ea96830c6551c40f44aca1ec4 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__socket_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__socket_8cpp__incl.dot new file mode 100644 index 0000000..2aa9d12 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__socket_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_socket.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__socket_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__socket_8cpp__incl.md5 new file mode 100644 index 0000000..bfe085b --- /dev/null +++ b/doc/doxygen/alc/html/mcl__socket_8cpp__incl.md5 @@ -0,0 +1 @@ +2cdf27897a053ec45483b0bef97a81fc \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__socket_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__socket_8h__dep__incl.dot new file mode 100644 index 0000000..f0bdf9b --- /dev/null +++ b/doc/doxygen/alc/html/mcl__socket_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_socket.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__socket_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__socket_8h__dep__incl.md5 new file mode 100644 index 0000000..365ad19 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__socket_8h__dep__incl.md5 @@ -0,0 +1 @@ +71a8263ebf673dcf40d5ac7e103e8ed0 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__socket__lib_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__socket__lib_8h__dep__incl.dot new file mode 100644 index 0000000..099ff4c --- /dev/null +++ b/doc/doxygen/alc/html/mcl__socket__lib_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_socket_lib.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__socket__lib_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__socket__lib_8h__dep__incl.md5 new file mode 100644 index 0000000..c9eab98 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__socket__lib_8h__dep__incl.md5 @@ -0,0 +1 @@ +ed4fdd3ad751a78681fa881995230232 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__stats_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__stats_8cpp__incl.dot new file mode 100644 index 0000000..d52e893 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__stats_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_stats.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__stats_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__stats_8cpp__incl.md5 new file mode 100644 index 0000000..1a62ecc --- /dev/null +++ b/doc/doxygen/alc/html/mcl__stats_8cpp__incl.md5 @@ -0,0 +1 @@ +001478217b25daf4257fb6ff3d79c5fd \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__stats_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__stats_8h__dep__incl.dot new file mode 100644 index 0000000..00b798b --- /dev/null +++ b/doc/doxygen/alc/html/mcl__stats_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_stats.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__stats_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__stats_8h__dep__incl.md5 new file mode 100644 index 0000000..4c96703 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__stats_8h__dep__incl.md5 @@ -0,0 +1 @@ +834f60d9382b17e7cc3bd9e682ecb2b5 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__tx_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__tx_8cpp__incl.dot new file mode 100644 index 0000000..72b0ad9 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_tx.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__tx_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__tx_8cpp__incl.md5 new file mode 100644 index 0000000..7bc5e5c --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx_8cpp__incl.md5 @@ -0,0 +1 @@ +ccb99258ee8daa24810b8b71d9192d3c \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__tx_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__tx_8h__dep__incl.dot new file mode 100644 index 0000000..acceb3b --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_tx.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__tx_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__tx_8h__dep__incl.md5 new file mode 100644 index 0000000..cbe6562 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx_8h__dep__incl.md5 @@ -0,0 +1 @@ +09d65da10703b0c30ca39361c85f8223 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__tx_8h__incl.dot b/doc/doxygen/alc/html/mcl__tx_8h__incl.dot new file mode 100644 index 0000000..594e2b7 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx_8h__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_tx.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_lib_api_alc.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api__alc_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__tx_8h__incl.md5 b/doc/doxygen/alc/html/mcl__tx_8h__incl.md5 new file mode 100644 index 0000000..10cf514 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx_8h__incl.md5 @@ -0,0 +1 @@ +20f40c8e90242630c3dc66edcf701a6e \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__tx__prof_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__tx__prof_8cpp__incl.dot new file mode 100644 index 0000000..4a046d2 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx__prof_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_tx_prof.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__tx__prof_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__tx__prof_8cpp__incl.md5 new file mode 100644 index 0000000..bf4a1ce --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx__prof_8cpp__incl.md5 @@ -0,0 +1 @@ +b95aab56218f73edfb1c32d50682da59 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__tx__tab_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__tx__tab_8cpp__incl.dot new file mode 100644 index 0000000..79bf1e7 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx__tab_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_tx_tab.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__tx__tab_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__tx__tab_8cpp__incl.md5 new file mode 100644 index 0000000..76578f2 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx__tab_8cpp__incl.md5 @@ -0,0 +1 @@ +7e45e3d6dc9347a349e5cc64280eab6a \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__tx__tab_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__tx__tab_8h__dep__incl.dot new file mode 100644 index 0000000..f94f270 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx__tab_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__tx__tab_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__tx__tab_8h__dep__incl.md5 new file mode 100644 index 0000000..ff03260 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__tx__tab_8h__dep__incl.md5 @@ -0,0 +1 @@ +5af960a12acf47ffe2bc057887de5a53 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__types_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__types_8h__dep__incl.dot new file mode 100644 index 0000000..90b1b3d --- /dev/null +++ b/doc/doxygen/alc/html/mcl__types_8h__dep__incl.dot @@ -0,0 +1,11 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_types.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; + Node3 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node2 -> Node3 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/mcl__types_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__types_8h__dep__incl.md5 new file mode 100644 index 0000000..38c9dc5 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__types_8h__dep__incl.md5 @@ -0,0 +1 @@ +c746c0793929ef3c4ba7ed9355a03b7c \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__version_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__version_8h__dep__incl.dot new file mode 100644 index 0000000..48f9eb4 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__version_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_version.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__version_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__version_8h__dep__incl.md5 new file mode 100644 index 0000000..98d0350 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__version_8h__dep__incl.md5 @@ -0,0 +1 @@ +fbaef2504b0d46cd082fa6eca8fc4d89 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__vrmem_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__vrmem_8cpp__incl.dot new file mode 100644 index 0000000..b49acc1 --- /dev/null +++ b/doc/doxygen/alc/html/mcl__vrmem_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_vrmem.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__vrmem_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__vrmem_8cpp__incl.md5 new file mode 100644 index 0000000..f2dfdee --- /dev/null +++ b/doc/doxygen/alc/html/mcl__vrmem_8cpp__incl.md5 @@ -0,0 +1 @@ +7a8e6732798703a5576567e5ca396896 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__vrmem_8h__dep__incl.dot b/doc/doxygen/alc/html/mcl__vrmem_8h__dep__incl.dot new file mode 100644 index 0000000..ef7fe0c --- /dev/null +++ b/doc/doxygen/alc/html/mcl__vrmem_8h__dep__incl.dot @@ -0,0 +1,11 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_vrmem.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node3 -> Node2 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/mcl__vrmem_8h__dep__incl.md5 b/doc/doxygen/alc/html/mcl__vrmem_8h__dep__incl.md5 new file mode 100644 index 0000000..aa92c3f --- /dev/null +++ b/doc/doxygen/alc/html/mcl__vrmem_8h__dep__incl.md5 @@ -0,0 +1 @@ +fd3d6f4a23081305923dd25710155a66 \ No newline at end of file diff --git a/doc/doxygen/alc/html/mcl__vtmem_8cpp__incl.dot b/doc/doxygen/alc/html/mcl__vtmem_8cpp__incl.dot new file mode 100644 index 0000000..748ab3c --- /dev/null +++ b/doc/doxygen/alc/html/mcl__vtmem_8cpp__incl.dot @@ -0,0 +1,141 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_vtmem.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node3 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node8 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node8 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node9 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node9 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node10 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node11 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node12 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node12 [label="sys/stat.h",height=0.2,width=0.4,color="grey75"]; + Node13 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node14 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node15 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [label="new",height=0.2,width=0.4,color="grey75"]; + Node16 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node17 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node17 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node18 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node18 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node19 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node19 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node20 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node20 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node21 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node21 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node22 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node22 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node23 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node23 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node24 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node24 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node25 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node25 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node26 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node26 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node27 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node27 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node28 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node28 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node29 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node29 [label="net/if.h",height=0.2,width=0.4,color="grey75"]; + Node30 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node30 [label="sys/ioctl.h",height=0.2,width=0.4,color="grey75"]; + Node31 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node31 [label="../common/mcl_types.h",height=0.2,width=0.4,color="black",URL="$mcl__types_8h.html"]; + Node32 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node32 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node33 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node33 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node34 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node34 [label="../common/mcl_defines.h",height=0.2,width=0.4,color="black",URL="$mcl__defines_8h.html"]; + Node35 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node35 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node31 -> Node35 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node36 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node37 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node37 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node38 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="../common/mcl_socket_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__socket__lib_8h.html"]; + Node39 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node39 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node40 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node40 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node41 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node41 [label="../common/mcl_blocking_struct.h",height=0.2,width=0.4,color="black",URL="$mcl__blocking__struct_8h.html"]; + Node42 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node42 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node43 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node43 [label="../common/mcl_file_io.h",height=0.2,width=0.4,color="black",URL="$mcl__file__io_8h.html"]; + Node44 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node44 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node45 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node45 [label="mcl_error.h",height=0.2,width=0.4,color="black",URL="$mcl__error_8h.html"]; + Node46 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node47 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node47 [label="mcl_lib.h",height=0.2,width=0.4,color="black",URL="$mcl__lib_8h.html"]; + Node48 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 [label="mcl_data.h",height=0.2,width=0.4,color="black",URL="$mcl__data_8h.html"]; + Node49 -> Node48 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node49 [label="mcl_vrmem.h",height=0.2,width=0.4,color="black",URL="$mcl__vrmem_8h.html"]; + Node49 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node50 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node51 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node51 [label="mcl_tx_tab.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__tab_8h.html"]; + Node52 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node52 [label="mcl_rlc.h",height=0.2,width=0.4,color="black",URL="$mcl__rlc_8h.html"]; + Node53 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node53 [label="mcl_flid_sl.h",height=0.2,width=0.4,color="black",URL="$mcl__flid__sl_8h.html"]; + Node54 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node54 [label="mcl_socket.h",height=0.2,width=0.4,color="black",URL="$mcl__socket_8h.html"]; + Node55 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node55 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node56 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node56 [label="mcl_lct_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__lct__hdr_8h.html"]; + Node57 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node57 [label="mcl_alc_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__alc__hdr_8h.html"]; + Node58 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node58 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node59 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node59 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node60 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node60 [label="mcl_proto.h",height=0.2,width=0.4,color="black",URL="$mcl__proto_8h.html"]; + Node61 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node61 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node62 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node62 [label="mcl_flute.h",height=0.2,width=0.4,color="black",URL="$mcl__flute_8h.html"]; + Node63 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node63 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node64 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node65 -> Node64 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node65 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node65 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node66 [label="mcl_meta_object.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object_8h.html"]; + Node67 -> Node2 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node67 [label="mcl_meta_object_layer.h",height=0.2,width=0.4,color="black",URL="$mcl__meta__object__layer_8h.html"]; +} diff --git a/doc/doxygen/alc/html/mcl__vtmem_8cpp__incl.md5 b/doc/doxygen/alc/html/mcl__vtmem_8cpp__incl.md5 new file mode 100644 index 0000000..2b24b8c --- /dev/null +++ b/doc/doxygen/alc/html/mcl__vtmem_8cpp__incl.md5 @@ -0,0 +1 @@ +ad9ea352566a8c2dbbb94e4ec7cafd82 \ No newline at end of file diff --git a/doc/doxygen/alc/html/rse__fec_8cpp__incl.dot b/doc/doxygen/alc/html/rse__fec_8cpp__incl.dot new file mode 100644 index 0000000..52e9eca --- /dev/null +++ b/doc/doxygen/alc/html/rse__fec_8cpp__incl.dot @@ -0,0 +1,18 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="rse_fec.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node3 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node3 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node4 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node5 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node5 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node6 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node6 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node7 -> Node1 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node7 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; +} diff --git a/doc/doxygen/alc/html/rse__fec_8cpp__incl.md5 b/doc/doxygen/alc/html/rse__fec_8cpp__incl.md5 new file mode 100644 index 0000000..0610b88 --- /dev/null +++ b/doc/doxygen/alc/html/rse__fec_8cpp__incl.md5 @@ -0,0 +1 @@ +b8cade2015a9684b3aea89946f367780 \ No newline at end of file diff --git a/doc/doxygen/alc/html/rse__fec_8h__dep__incl.dot b/doc/doxygen/alc/html/rse__fec_8h__dep__incl.dot new file mode 100644 index 0000000..a2b8879 --- /dev/null +++ b/doc/doxygen/alc/html/rse__fec_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="rse_fec.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/alc/html/rse__fec_8h__dep__incl.md5 b/doc/doxygen/alc/html/rse__fec_8h__dep__incl.md5 new file mode 100644 index 0000000..d946aad --- /dev/null +++ b/doc/doxygen/alc/html/rse__fec_8h__dep__incl.md5 @@ -0,0 +1 @@ +54d23dbe6af069855b583b94bfab4767 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structadu__coll__graph.dot b/doc/doxygen/alc/html/structadu__coll__graph.dot new file mode 100644 index 0000000..7f5a517 --- /dev/null +++ b/doc/doxygen/alc/html/structadu__coll__graph.dot @@ -0,0 +1,18 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="adu",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="blocking_struct",fontname="Helvetica"]; + Node2 [label="mcl_blocking_struct",height=0.2,width=0.4,color="black",URL="$structmcl__blocking__struct.html"]; + Node3 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node3 [label="block",height=0.2,width=0.4,color="black",URL="$structblock.html"]; + Node4 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node4 [label="du",height=0.2,width=0.4,color="red",URL="$structdu.html"]; + Node4 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node3 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node1 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node1 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node5 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node5 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; +} diff --git a/doc/doxygen/alc/html/structadu__coll__graph.md5 b/doc/doxygen/alc/html/structadu__coll__graph.md5 new file mode 100644 index 0000000..a3295da --- /dev/null +++ b/doc/doxygen/alc/html/structadu__coll__graph.md5 @@ -0,0 +1 @@ +b392e9c9070946bc0c56d8e604a385d4 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structblock__coll__graph.dot b/doc/doxygen/alc/html/structblock__coll__graph.dot new file mode 100644 index 0000000..e79091a --- /dev/null +++ b/doc/doxygen/alc/html/structblock__coll__graph.dot @@ -0,0 +1,14 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="block",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node2 [label="du",height=0.2,width=0.4,color="red",URL="$structdu.html"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node1 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node3 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node3 [label="adu",height=0.2,width=0.4,color="red",URL="$structadu.html"]; + Node1 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node3 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/structblock__coll__graph.md5 b/doc/doxygen/alc/html/structblock__coll__graph.md5 new file mode 100644 index 0000000..7903381 --- /dev/null +++ b/doc/doxygen/alc/html/structblock__coll__graph.md5 @@ -0,0 +1 @@ +418f26860962819f5d4869141fbca017 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structdu__coll__graph.dot b/doc/doxygen/alc/html/structdu__coll__graph.dot new file mode 100644 index 0000000..6721f2a --- /dev/null +++ b/doc/doxygen/alc/html/structdu__coll__graph.dot @@ -0,0 +1,16 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="du",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="pkt",fontname="Helvetica"]; + Node2 [label="mcl_rx_pkt",height=0.2,width=0.4,color="black",URL="$classmcl__rx__pkt.html"]; + Node3 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node3 [label="block",height=0.2,width=0.4,color="black",URL="$structblock.html"]; + Node1 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node4 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node4 [label="adu",height=0.2,width=0.4,color="red",URL="$structadu.html"]; + Node3 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node4 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/structdu__coll__graph.md5 b/doc/doxygen/alc/html/structdu__coll__graph.md5 new file mode 100644 index 0000000..63498ed --- /dev/null +++ b/doc/doxygen/alc/html/structdu__coll__graph.md5 @@ -0,0 +1 @@ +bd35a5449aae6a34dd6c4b42345285f0 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structidx__range__t__coll__graph.dot b/doc/doxygen/alc/html/structidx__range__t__coll__graph.dot new file mode 100644 index 0000000..30b6689 --- /dev/null +++ b/doc/doxygen/alc/html/structidx__range__t__coll__graph.dot @@ -0,0 +1,16 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="idx_range_t",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node2 [label="adu",height=0.2,width=0.4,color="black",URL="$structadu.html"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="blocking_struct",fontname="Helvetica"]; + Node3 [label="mcl_blocking_struct",height=0.2,width=0.4,color="black",URL="$structmcl__blocking__struct.html"]; + Node4 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node4 [label="block",height=0.2,width=0.4,color="red",URL="$structblock.html"]; + Node2 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node5 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node5 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; +} diff --git a/doc/doxygen/alc/html/structidx__range__t__coll__graph.md5 b/doc/doxygen/alc/html/structidx__range__t__coll__graph.md5 new file mode 100644 index 0000000..67fe514 --- /dev/null +++ b/doc/doxygen/alc/html/structidx__range__t__coll__graph.md5 @@ -0,0 +1 @@ +d1da557f33471758cd397845d115c603 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structlist__of__meta__objects__coll__graph.dot b/doc/doxygen/alc/html/structlist__of__meta__objects__coll__graph.dot new file mode 100644 index 0000000..0b2bf44 --- /dev/null +++ b/doc/doxygen/alc/html/structlist__of__meta__objects__coll__graph.dot @@ -0,0 +1,68 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="list_of_meta_objects",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="meta_obj",fontname="Helvetica"]; + Node2 [label="mcl_meta_object",height=0.2,width=0.4,color="black",URL="$classmcl__meta__object.html"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="mclcb",fontname="Helvetica"]; + Node3 [label="mcl_cb",height=0.2,width=0.4,color="black",URL="$classmcl__cb.html"]; + Node4 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fsm",fontname="Helvetica"]; + Node4 [label="mcl_fsm",height=0.2,width=0.4,color="black",URL="$classmcl__fsm.html"]; + Node5 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket_tab",fontname="Helvetica"]; + Node5 [label="mcl_socket",height=0.2,width=0.4,color="black",URL="$classmcl__socket.html"]; + Node6 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node6 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node7 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rxlvl",fontname="Helvetica"]; + Node7 [label="rxlay_t",height=0.2,width=0.4,color="black",URL="$structrxlay__t.html"]; + Node8 -> Node7 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node8 [label="du",height=0.2,width=0.4,color="black",URL="$structdu.html"]; + Node8 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node9 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node9 [label="block",height=0.2,width=0.4,color="black",URL="$structblock.html"]; + Node8 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node10 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node10 [label="adu",height=0.2,width=0.4,color="black",URL="$structadu.html"]; + Node9 -> Node10 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node10 -> Node10 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node6 -> Node10 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node5 -> Node7 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket_head",fontname="Helvetica"]; + Node11 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_flute",fontname="Helvetica"]; + Node11 [label="mcl_rx_flute",height=0.2,width=0.4,color="black",URL="$classmcl__rx__flute.html"]; + Node12 -> Node11 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="desired_tois",fontname="Helvetica"]; + Node12 [label="mcl_toi_list",height=0.2,width=0.4,color="black",URL="$structmcl__toi__list.html"]; + Node12 -> Node12 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node13 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_window",fontname="Helvetica"]; + Node13 [label="mcl_rx_window",height=0.2,width=0.4,color="black",URL="$classmcl__rx__window.html"]; + Node10 -> Node13 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head\nnext_ordered_adu_to_return",fontname="Helvetica"]; + Node14 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_flute",fontname="Helvetica"]; + Node14 [label="mcl_tx_flute",height=0.2,width=0.4,color="black",URL="$classmcl__tx__flute.html"]; + Node15 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="txlay_tab",fontname="Helvetica"]; + Node15 [label="txlay",height=0.2,width=0.4,color="black",URL="$structtxlay.html"]; + Node5 -> Node15 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket",fontname="Helvetica"]; + Node16 -> Node15 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_tab\ntx_tab_high",fontname="Helvetica"]; + Node16 [label="mcl_tx_tab",height=0.2,width=0.4,color="red",URL="$classmcl__tx__tab.html"]; + Node17 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="stats",fontname="Helvetica"]; + Node17 [label="stats_t",height=0.2,width=0.4,color="black",URL="$structstats__t.html"]; + Node18 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fec",fontname="Helvetica"]; + Node18 [label="mcl_fec",height=0.2,width=0.4,color="black",URL="$classmcl__fec.html"]; + Node19 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="periodic_proc",fontname="Helvetica"]; + Node19 [label="mcl_periodic_proc",height=0.2,width=0.4,color="black",URL="$classmcl__periodic__proc.html"]; + Node10 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="findadu_cache\nlastadu_cache",fontname="Helvetica"]; + Node20 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="sig_tab\npsig_next",fontname="Helvetica"]; + Node20 [label="sig_tab",height=0.2,width=0.4,color="black",URL="$structsig__tab.html"]; + Node6 -> Node20 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="saddr",fontname="Helvetica"]; + Node20 -> Node20 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node6 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr\nmcast_if_addr\nsrc_addr",fontname="Helvetica"]; + Node21 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx",fontname="Helvetica"]; + Node21 [label="mcl_tx",height=0.2,width=0.4,color="black",URL="$classmcl__tx.html"]; + Node10 -> Node21 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_start\nadu_head\nadu_end",fontname="Helvetica"]; + Node22 -> Node3 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_storage",fontname="Helvetica"]; + Node22 [label="mcl_rx_storage",height=0.2,width=0.4,color="black",URL="$classmcl__rx__storage.html"]; + Node23 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="object_list_tail\nfindobject_cache\nobject_list_head",fontname="Helvetica"]; + Node23 [label="object",height=0.2,width=0.4,color="black",URL="$structobject.html"]; + Node8 -> Node23 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="first_du\nlast_decoded_du",fontname="Helvetica"]; + Node9 -> Node23 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="first_blk",fontname="Helvetica"]; + Node23 -> Node23 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node1 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/structlist__of__meta__objects__coll__graph.md5 b/doc/doxygen/alc/html/structlist__of__meta__objects__coll__graph.md5 new file mode 100644 index 0000000..52b5b01 --- /dev/null +++ b/doc/doxygen/alc/html/structlist__of__meta__objects__coll__graph.md5 @@ -0,0 +1 @@ +09eb32a7558ba30e5686b3e1083a2db8 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structmcl__toi__list__coll__graph.dot b/doc/doxygen/alc/html/structmcl__toi__list__coll__graph.dot new file mode 100644 index 0000000..99417b2 --- /dev/null +++ b/doc/doxygen/alc/html/structmcl__toi__list__coll__graph.dot @@ -0,0 +1,7 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="mcl_toi_list",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/structmcl__toi__list__coll__graph.md5 b/doc/doxygen/alc/html/structmcl__toi__list__coll__graph.md5 new file mode 100644 index 0000000..438de9d --- /dev/null +++ b/doc/doxygen/alc/html/structmcl__toi__list__coll__graph.md5 @@ -0,0 +1 @@ +5a0c046d12cf42e51d9ceaffb2e82b19 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structobject__coll__graph.dot b/doc/doxygen/alc/html/structobject__coll__graph.dot new file mode 100644 index 0000000..6ff3676 --- /dev/null +++ b/doc/doxygen/alc/html/structobject__coll__graph.dot @@ -0,0 +1,16 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="object",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="first_du\nlast_decoded_du",fontname="Helvetica"]; + Node2 [label="du",height=0.2,width=0.4,color="black",URL="$structdu.html"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="pkt",fontname="Helvetica"]; + Node3 [label="mcl_rx_pkt",height=0.2,width=0.4,color="black",URL="$classmcl__rx__pkt.html"]; + Node4 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node4 [label="block",height=0.2,width=0.4,color="black",URL="$structblock.html"]; + Node2 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node4 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="first_blk",fontname="Helvetica"]; + Node1 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/structobject__coll__graph.md5 b/doc/doxygen/alc/html/structobject__coll__graph.md5 new file mode 100644 index 0000000..a3f0455 --- /dev/null +++ b/doc/doxygen/alc/html/structobject__coll__graph.md5 @@ -0,0 +1 @@ +23af5242ac6b38794f308eb9aa4dc549 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structrxlay__t__coll__graph.dot b/doc/doxygen/alc/html/structrxlay__t__coll__graph.dot new file mode 100644 index 0000000..1d22eed --- /dev/null +++ b/doc/doxygen/alc/html/structrxlay__t__coll__graph.dot @@ -0,0 +1,18 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="rxlay_t",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node2 [label="du",height=0.2,width=0.4,color="black",URL="$structdu.html"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="pkt",fontname="Helvetica"]; + Node3 [label="mcl_rx_pkt",height=0.2,width=0.4,color="black",URL="$classmcl__rx__pkt.html"]; + Node4 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node4 [label="block",height=0.2,width=0.4,color="red",URL="$structblock.html"]; + Node2 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node5 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket_head",fontname="Helvetica"]; + Node5 [label="mcl_socket",height=0.2,width=0.4,color="black",URL="$classmcl__socket.html"]; + Node6 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node6 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; +} diff --git a/doc/doxygen/alc/html/structrxlay__t__coll__graph.md5 b/doc/doxygen/alc/html/structrxlay__t__coll__graph.md5 new file mode 100644 index 0000000..07375b7 --- /dev/null +++ b/doc/doxygen/alc/html/structrxlay__t__coll__graph.md5 @@ -0,0 +1 @@ +6f5d66e210cf8e536edd388e0f1e1fb3 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structsig__tab__coll__graph.dot b/doc/doxygen/alc/html/structsig__tab__coll__graph.dot new file mode 100644 index 0000000..d74c1d9 --- /dev/null +++ b/doc/doxygen/alc/html/structsig__tab__coll__graph.dot @@ -0,0 +1,9 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="sig_tab",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="saddr",fontname="Helvetica"]; + Node2 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node1 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/structsig__tab__coll__graph.md5 b/doc/doxygen/alc/html/structsig__tab__coll__graph.md5 new file mode 100644 index 0000000..79e39bc --- /dev/null +++ b/doc/doxygen/alc/html/structsig__tab__coll__graph.md5 @@ -0,0 +1 @@ +cbef69b309a207dc92b0079d61ecd0c3 \ No newline at end of file diff --git a/doc/doxygen/alc/html/structtxlay__coll__graph.dot b/doc/doxygen/alc/html/structtxlay__coll__graph.dot new file mode 100644 index 0000000..e745918 --- /dev/null +++ b/doc/doxygen/alc/html/structtxlay__coll__graph.dot @@ -0,0 +1,18 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="txlay",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="socket",fontname="Helvetica"]; + Node2 [label="mcl_socket",height=0.2,width=0.4,color="black",URL="$classmcl__socket.html"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node3 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node4 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_tab\ntx_tab_high",fontname="Helvetica"]; + Node4 [label="mcl_tx_tab",height=0.2,width=0.4,color="black",URL="$classmcl__tx__tab.html"]; + Node5 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="cached_txtab\ntxtab_head",fontname="Helvetica"]; + Node5 [label="txtab",height=0.2,width=0.4,color="black",URL="$structtxtab.html"]; + Node6 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_tab",fontname="Helvetica"]; + Node6 [label="du",height=0.2,width=0.4,color="red",URL="$structdu.html"]; + Node6 -> Node6 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node5 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/structtxlay__coll__graph.md5 b/doc/doxygen/alc/html/structtxlay__coll__graph.md5 new file mode 100644 index 0000000..ceb9dbc --- /dev/null +++ b/doc/doxygen/alc/html/structtxlay__coll__graph.md5 @@ -0,0 +1 @@ +a93f57442e889a453e3d679e0d79ce0c \ No newline at end of file diff --git a/doc/doxygen/alc/html/structtxtab__coll__graph.dot b/doc/doxygen/alc/html/structtxtab__coll__graph.dot new file mode 100644 index 0000000..eae329f --- /dev/null +++ b/doc/doxygen/alc/html/structtxtab__coll__graph.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1 [label="txtab",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_tab",fontname="Helvetica"]; + Node2 [label="du",height=0.2,width=0.4,color="black",URL="$structdu.html"]; + Node2 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node3 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="pkt",fontname="Helvetica"]; + Node3 [label="mcl_rx_pkt",height=0.2,width=0.4,color="black",URL="$classmcl__rx__pkt.html"]; + Node4 -> Node2 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node4 [label="block",height=0.2,width=0.4,color="red",URL="$structblock.html"]; + Node2 -> Node4 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head",fontname="Helvetica"]; + Node1 -> Node1 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/alc/html/structtxtab__coll__graph.md5 b/doc/doxygen/alc/html/structtxtab__coll__graph.md5 new file mode 100644 index 0000000..48ec938 --- /dev/null +++ b/doc/doxygen/alc/html/structtxtab__coll__graph.md5 @@ -0,0 +1 @@ +aa621a58838bea63308581ac1984bb21 \ No newline at end of file diff --git a/doc/doxygen/norm/Doxyfile b/doc/doxygen/norm/Doxyfile new file mode 100644 index 0000000..1d76aaa --- /dev/null +++ b/doc/doxygen/norm/Doxyfile @@ -0,0 +1,970 @@ +# Doxyfile 1.2.17 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# General configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = mclv3 + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, +# Finnish, French, German, Greek, Hungarian, Italian, Japanese, Japanese-en +# (Japanese with english messages), Korean, Norwegian, Polish, Portuguese, +# Romanian, Russian, Serbian, Slovak, Slovene, Spanish, Swedish and Ukrainian. + +OUTPUT_LANGUAGE = English + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = YES + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these class will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. It is allowed to use relative paths in the argument list. + +#STRIP_FROM_PATH = /mnt/iseran/roca/work/mclv3/ +STRIP_FROM_PATH = /home/roca/work/mclv3/ + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower case letters. If set to YES upper case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# users are adviced to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explict @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# reimplements. + +INHERIT_DOCS = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consist of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = ../../../src/norm ../../../src/common + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. + +INPUT_FILTER = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse. + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output dir. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non empty doxygen will try to run +# the html help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the Html help documentation and to the tree view. + +TOC_EXPAND = YES + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript and frames is required (for instance Mozilla, Netscape 4.0+, +# or Internet explorer 4.0+). Note that for large projects the tree generation +# can take a very long time. In such cases it is better to disable this feature. +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimised for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assigments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = YES + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_XML = NO + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES tag can be used to specify one or more tagfiles. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in Html, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superceded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yield more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermedate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::addtions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO + +# The CGI_NAME tag should be the name of the CGI script that +# starts the search engine (doxysearch) with the correct parameters. +# A script with this name will be generated by doxygen. + +CGI_NAME = search.cgi + +# The CGI_URL tag should be the absolute URL to the directory where the +# cgi binaries are located. See the documentation of your http daemon for +# details. + +CGI_URL = + +# The DOC_URL tag should be the absolute URL to the directory where the +# documentation is located. If left blank the absolute path to the +# documentation, with file:// prepended to it, will be used. + +DOC_URL = + +# The DOC_ABSPATH tag should be the absolute path to the directory where the +# documentation is located. If left blank the directory on the local machine +# will be used. + +DOC_ABSPATH = + +# The BIN_ABSPATH tag must point to the directory where the doxysearch binary +# is installed. + +BIN_ABSPATH = /usr/local/bin/ + +# The EXT_DOC_PATHS tag can be used to specify one or more paths to +# documentation generated for other projects. This allows doxysearch to search +# the documentation for these projects as well. + +EXT_DOC_PATHS = diff --git a/doc/doxygen/norm/html/classmcl__adu__coll__graph.dot b/doc/doxygen/norm/html/classmcl__adu__coll__graph.dot new file mode 100644 index 0000000..34a72cb --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__adu__coll__graph.dot @@ -0,0 +1,16 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node5 [label="mcl_adu",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node5 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node6 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node6 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node7 -> Node5 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node7 [label="mcl_block",height=0.2,width=0.4,color="black",URL="$classmcl__block.html"]; + Node5 -> Node7 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node8 -> Node7 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head\nfec_du_head",fontname="Helvetica"]; + Node8 [label="mcl_du",height=0.2,width=0.4,color="red",URL="$classmcl__du.html"]; + Node8 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext\ntx_next\ntx_prev",fontname="Helvetica"]; + Node7 -> Node8 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__block__coll__graph.dot b/doc/doxygen/norm/html/classmcl__block__coll__graph.dot new file mode 100644 index 0000000..cd2a1dc --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__block__coll__graph.dot @@ -0,0 +1,14 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node11 [label="mcl_block",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node12 -> Node11 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node12 [label="mcl_adu",height=0.2,width=0.4,color="red",URL="$classmcl__adu.html"]; + Node12 -> Node12 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node11 -> Node12 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node14 -> Node11 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head\nfec_du_head",fontname="Helvetica"]; + Node14 [label="mcl_du",height=0.2,width=0.4,color="red",URL="$classmcl__du.html"]; + Node14 -> Node14 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext\ntx_next\ntx_prev",fontname="Helvetica"]; + Node11 -> Node14 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__cb__coll__graph.dot b/doc/doxygen/norm/html/classmcl__cb__coll__graph.dot new file mode 100644 index 0000000..27f1bff --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__cb__coll__graph.dot @@ -0,0 +1,78 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node19 [label="mcl_cb",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node20 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx",fontname="Helvetica"]; + Node20 [label="mcl_rx",height=0.2,width=0.4,color="black",URL="$classmcl__rx.html"]; + Node21 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="ses_channel",fontname="Helvetica"]; + Node21 [label="mcl_ses_channel",height=0.2,width=0.4,color="black",URL="$classmcl__ses__channel.html"]; + Node22 -> Node21 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="priv_addr\nmcast_if\nses_addr",fontname="Helvetica"]; + Node22 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node23 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fsm",fontname="Helvetica"]; + Node23 [label="mcl_fsm",height=0.2,width=0.4,color="black",URL="$classmcl__fsm.html"]; + Node24 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="group_mgmt",fontname="Helvetica"]; + Node24 [label="mcl_group_mgmt",height=0.2,width=0.4,color="black",URL="$classmcl__group__mgmt.html"]; + Node25 -> Node24 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="head\ntail\ncur_member\nmember_tab",fontname="Helvetica"]; + Node25 [label="mcl_node",height=0.2,width=0.4,color="black",URL="$classmcl__node.html"]; + Node25 -> Node25 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node29 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_window",fontname="Helvetica"]; + Node29 [label="mcl_tx_window",height=0.2,width=0.4,color="black",URL="$classmcl__tx__window.html"]; + Node30 -> Node29 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_list_head\nhp_du_list_head\nhp_du_list_snd_max\ndu_list_snd_max",fontname="Helvetica"]; + Node30 [label="mcl_du",height=0.2,width=0.4,color="red",URL="$classmcl__du.html"]; + Node30 -> Node30 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext\ntx_next\ntx_prev",fontname="Helvetica"]; + Node32 -> Node30 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node32 [label="mcl_block",height=0.2,width=0.4,color="black",URL="$classmcl__block.html"]; + Node33 -> Node32 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node33 [label="mcl_adu",height=0.2,width=0.4,color="black",URL="$classmcl__adu.html"]; + Node33 -> Node33 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node22 -> Node33 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node32 -> Node33 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node30 -> Node32 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head\nfec_du_head",fontname="Helvetica"]; + Node32 -> Node29 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="blist_head\nblist_snd_una\nblist_snd_max\nblist_tail",fontname="Helvetica"]; + Node34 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="stats",fontname="Helvetica"]; + Node34 [label="mcl_stats",height=0.2,width=0.4,color="black",URL="$classmcl__stats.html"]; + Node35 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="norm_pkt_mgmt",fontname="Helvetica"]; + Node35 [label="mcl_norm_pkt_mgmt",height=0.2,width=0.4,color="black",URL="$classmcl__norm__pkt__mgmt.html"]; + Node36 -> Node35 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next_nack_content_ptr",fontname="Helvetica"]; + Node36 [label="norm_nack_content_hdr_t",height=0.2,width=0.4,color="black",URL="$structnorm__nack__content__hdr__t.html"]; + Node25 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="node",fontname="Helvetica"]; + Node37 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_window",fontname="Helvetica"]; + Node37 [label="mcl_rx_window",height=0.2,width=0.4,color="black",URL="$classmcl__rx__window.html"]; + Node33 -> Node37 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head",fontname="Helvetica"]; + Node30 -> Node37 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_list_head",fontname="Helvetica"]; + Node38 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fec",fontname="Helvetica"]; + Node38 [label="mcl_fec",height=0.2,width=0.4,color="black",URL="$classmcl__fec.html"]; + Node39 -> Node38 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fec_encoding_thread",fontname="Helvetica"]; + Node39 [label="mcl_fec_thread",height=0.2,width=0.4,color="black",URL="$classmcl__fec__thread.html"]; + Node40 -> Node38 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fec_job_list",fontname="Helvetica"]; + Node40 [label="mcl_fec_job_list",height=0.2,width=0.4,color="red",URL="$classmcl__fec__job__list.html"]; + Node42 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="periodic_proc",fontname="Helvetica"]; + Node42 [label="mcl_periodic_proc",height=0.2,width=0.4,color="black",URL="$classmcl__periodic__proc.html"]; + Node43 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="timer",fontname="Helvetica"]; + Node43 [label="mcl_timer",height=0.2,width=0.4,color="black",URL="$classmcl__timer.html"]; + Node44 -> Node43 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="object",fontname="Helvetica"]; + Node44 [label="mcl_timer_handler",height=0.2,width=0.4,color="black",URL="$classmcl__timer__handler.html"]; + Node45 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_ctrl",fontname="Helvetica"]; + Node45 [label="mcl_rx_ctrl",height=0.2,width=0.4,color="black",URL="$classmcl__rx__ctrl.html"]; + Node44 -> Node45 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node46 -> Node45 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="NACK_tevent_head",fontname="Helvetica"]; + Node46 [label="mcl_rx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__rx__ctrl__tevent.html"]; + Node46 -> Node46 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node47 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_ctrl",fontname="Helvetica"]; + Node47 [label="mcl_tx_ctrl",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl.html"]; + Node44 -> Node47 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node48 -> Node47 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="RETX_DONE_tevent_head\nFLUSH_DONE_tevent_head",fontname="Helvetica"]; + Node48 [label="mcl_tx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl__tevent.html"]; + Node48 -> Node48 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node32 -> Node47 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="blk_of_last_du",fontname="Helvetica"]; + Node49 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx_storage",fontname="Helvetica"]; + Node49 [label="mcl_tx_storage",height=0.2,width=0.4,color="black",URL="$classmcl__tx__storage.html"]; + Node50 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_thread",fontname="Helvetica"]; + Node50 [label="mcl_rx_thread",height=0.2,width=0.4,color="black",URL="$classmcl__rx__thread.html"]; + Node51 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="tx",fontname="Helvetica"]; + Node51 [label="mcl_tx",height=0.2,width=0.4,color="black",URL="$classmcl__tx.html"]; + Node33 -> Node51 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head",fontname="Helvetica"]; + Node52 -> Node19 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="rx_storage",fontname="Helvetica"]; + Node52 [label="mcl_rx_storage",height=0.2,width=0.4,color="black",URL="$classmcl__rx__storage.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__du__coll__graph.dot b/doc/doxygen/norm/html/classmcl__du__coll__graph.dot new file mode 100644 index 0000000..cbf7d54 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__du__coll__graph.dot @@ -0,0 +1,16 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node58 [label="mcl_du",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node59 -> Node58 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="pkt",fontname="Helvetica"]; + Node59 [label="mcl_rx_pkt",height=0.2,width=0.4,color="black",URL="$classmcl__rx__pkt.html"]; + Node58 -> Node58 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext\ntx_next\ntx_prev",fontname="Helvetica"]; + Node60 -> Node58 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node60 [label="mcl_block",height=0.2,width=0.4,color="black",URL="$classmcl__block.html"]; + Node61 -> Node60 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node61 [label="mcl_adu",height=0.2,width=0.4,color="red",URL="$classmcl__adu.html"]; + Node61 -> Node61 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node60 -> Node61 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node58 -> Node60 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head\nfec_du_head",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__fec__coll__graph.dot b/doc/doxygen/norm/html/classmcl__fec__coll__graph.dot new file mode 100644 index 0000000..2299d73 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__fec__coll__graph.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node64 [label="mcl_fec",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node65 -> Node64 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fec_encoding_thread",fontname="Helvetica"]; + Node65 [label="mcl_fec_thread",height=0.2,width=0.4,color="black",URL="$classmcl__fec__thread.html"]; + Node66 -> Node64 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="fec_job_list",fontname="Helvetica"]; + Node66 [label="mcl_fec_job_list",height=0.2,width=0.4,color="black",URL="$classmcl__fec__job__list.html"]; + Node67 -> Node66 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="head\ntail",fontname="Helvetica"]; + Node67 [label="mcl_fec_job",height=0.2,width=0.4,color="black",URL="$classmcl__fec__job.html"]; + Node67 -> Node67 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node68 -> Node67 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node68 [label="mcl_block",height=0.2,width=0.4,color="red",URL="$classmcl__block.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__fec__job__coll__graph.dot b/doc/doxygen/norm/html/classmcl__fec__job__coll__graph.dot new file mode 100644 index 0000000..6ee4183 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__fec__job__coll__graph.dot @@ -0,0 +1,17 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node74 [label="mcl_fec_job",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node74 -> Node74 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node75 -> Node74 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node75 [label="mcl_block",height=0.2,width=0.4,color="black",URL="$classmcl__block.html"]; + Node76 -> Node75 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node76 [label="mcl_adu",height=0.2,width=0.4,color="red",URL="$classmcl__adu.html"]; + Node76 -> Node76 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node75 -> Node76 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node78 -> Node75 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head\nfec_du_head",fontname="Helvetica"]; + Node78 [label="mcl_du",height=0.2,width=0.4,color="red",URL="$classmcl__du.html"]; + Node78 -> Node78 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext\ntx_next\ntx_prev",fontname="Helvetica"]; + Node75 -> Node78 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__fec__job__list__coll__graph.dot b/doc/doxygen/norm/html/classmcl__fec__job__list__coll__graph.dot new file mode 100644 index 0000000..ab3be89 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__fec__job__list__coll__graph.dot @@ -0,0 +1,11 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node81 [label="mcl_fec_job_list",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node82 -> Node81 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="head\ntail",fontname="Helvetica"]; + Node82 [label="mcl_fec_job",height=0.2,width=0.4,color="black",URL="$classmcl__fec__job.html"]; + Node82 -> Node82 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next",fontname="Helvetica"]; + Node83 -> Node82 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node83 [label="mcl_block",height=0.2,width=0.4,color="red",URL="$classmcl__block.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__group__mgmt__coll__graph.dot b/doc/doxygen/norm/html/classmcl__group__mgmt__coll__graph.dot new file mode 100644 index 0000000..fa7bf7b --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__group__mgmt__coll__graph.dot @@ -0,0 +1,9 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node93 [label="mcl_group_mgmt",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node94 -> Node93 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="head\ntail\ncur_member\nmember_tab",fontname="Helvetica"]; + Node94 [label="mcl_node",height=0.2,width=0.4,color="red",URL="$classmcl__node.html"]; + Node94 -> Node94 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__node__coll__graph.dot b/doc/doxygen/norm/html/classmcl__node__coll__graph.dot new file mode 100644 index 0000000..38b3436 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__node__coll__graph.dot @@ -0,0 +1,13 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node99 [label="mcl_node",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node100 -> Node99 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="n_stats",fontname="Helvetica"]; + Node100 [label="node_stats_t",height=0.2,width=0.4,color="black",URL="$structnode__stats__t.html"]; + Node101 -> Node99 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="r_stats",fontname="Helvetica"]; + Node101 [label="receiver_stats_t",height=0.2,width=0.4,color="black",URL="$structreceiver__stats__t.html"]; + Node102 -> Node99 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="s_stats",fontname="Helvetica"]; + Node102 [label="source_stats_t",height=0.2,width=0.4,color="black",URL="$structsource__stats__t.html"]; + Node99 -> Node99 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__norm__pkt__mgmt__coll__graph.dot b/doc/doxygen/norm/html/classmcl__norm__pkt__mgmt__coll__graph.dot new file mode 100644 index 0000000..3d2eb96 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__norm__pkt__mgmt__coll__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node104 [label="mcl_norm_pkt_mgmt",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node105 -> Node104 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="next_nack_content_ptr",fontname="Helvetica"]; + Node105 [label="norm_nack_content_hdr_t",height=0.2,width=0.4,color="black",URL="$structnorm__nack__content__hdr__t.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__rx__ctrl__NACK__tevent__coll__graph.dot b/doc/doxygen/norm/html/classmcl__rx__ctrl__NACK__tevent__coll__graph.dot new file mode 100644 index 0000000..7b3a130 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__rx__ctrl__NACK__tevent__coll__graph.dot @@ -0,0 +1,11 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node119 [label="mcl_rx_ctrl_NACK_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node120 -> Node119 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node120 [label="mcl_rx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__rx__ctrl__tevent.html"]; + Node120 -> Node120 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node121 -> Node119 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="src_addr",fontname="Helvetica"]; + Node121 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__rx__ctrl__NACK__tevent__inherit__graph.dot b/doc/doxygen/norm/html/classmcl__rx__ctrl__NACK__tevent__inherit__graph.dot new file mode 100644 index 0000000..8567893 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__rx__ctrl__NACK__tevent__inherit__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node117 [label="mcl_rx_ctrl_NACK_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node118 -> Node117 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node118 [label="mcl_rx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__rx__ctrl__tevent.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__rx__ctrl__coll__graph.dot b/doc/doxygen/norm/html/classmcl__rx__ctrl__coll__graph.dot new file mode 100644 index 0000000..308abd6 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__rx__ctrl__coll__graph.dot @@ -0,0 +1,11 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node114 [label="mcl_rx_ctrl",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node115 -> Node114 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node115 [label="mcl_timer_handler",height=0.2,width=0.4,color="black",URL="$classmcl__timer__handler.html"]; + Node116 -> Node114 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="NACK_tevent_head",fontname="Helvetica"]; + Node116 [label="mcl_rx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__rx__ctrl__tevent.html"]; + Node116 -> Node116 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__rx__ctrl__inherit__graph.dot b/doc/doxygen/norm/html/classmcl__rx__ctrl__inherit__graph.dot new file mode 100644 index 0000000..6c04306 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__rx__ctrl__inherit__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node112 [label="mcl_rx_ctrl",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node113 -> Node112 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node113 [label="mcl_timer_handler",height=0.2,width=0.4,color="black",URL="$classmcl__timer__handler.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__rx__ctrl__tevent__coll__graph.dot b/doc/doxygen/norm/html/classmcl__rx__ctrl__tevent__coll__graph.dot new file mode 100644 index 0000000..56de43e --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__rx__ctrl__tevent__coll__graph.dot @@ -0,0 +1,7 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node124 [label="mcl_rx_ctrl_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node124 -> Node124 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__rx__ctrl__tevent__inherit__graph.dot b/doc/doxygen/norm/html/classmcl__rx__ctrl__tevent__inherit__graph.dot new file mode 100644 index 0000000..2db72c9 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__rx__ctrl__tevent__inherit__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node122 [label="mcl_rx_ctrl_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node122 -> Node123 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node123 [label="mcl_rx_ctrl_NACK_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__rx__ctrl__NACK__tevent.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__rx__window__coll__graph.dot b/doc/doxygen/norm/html/classmcl__rx__window__coll__graph.dot new file mode 100644 index 0000000..e92c85f --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__rx__window__coll__graph.dot @@ -0,0 +1,19 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node132 [label="mcl_rx_window",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node133 -> Node132 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head",fontname="Helvetica"]; + Node133 [label="mcl_adu",height=0.2,width=0.4,color="black",URL="$classmcl__adu.html"]; + Node133 -> Node133 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node134 -> Node133 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node134 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node135 -> Node133 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node135 [label="mcl_block",height=0.2,width=0.4,color="black",URL="$classmcl__block.html"]; + Node133 -> Node135 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node136 -> Node135 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head\nfec_du_head",fontname="Helvetica"]; + Node136 [label="mcl_du",height=0.2,width=0.4,color="black",URL="$classmcl__du.html"]; + Node136 -> Node136 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext\ntx_next\ntx_prev",fontname="Helvetica"]; + Node135 -> Node136 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node136 -> Node132 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_list_head",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__ses__channel__coll__graph.dot b/doc/doxygen/norm/html/classmcl__ses__channel__coll__graph.dot new file mode 100644 index 0000000..2526b13 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__ses__channel__coll__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node139 [label="mcl_ses_channel",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node140 -> Node139 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="priv_addr\nmcast_if\nses_addr",fontname="Helvetica"]; + Node140 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__timer__coll__graph.dot b/doc/doxygen/norm/html/classmcl__timer__coll__graph.dot new file mode 100644 index 0000000..fc766a9 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__timer__coll__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node144 [label="mcl_timer",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node145 -> Node144 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="object",fontname="Helvetica"]; + Node145 [label="mcl_timer_handler",height=0.2,width=0.4,color="black",URL="$classmcl__timer__handler.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__timer__handler__inherit__graph.dot b/doc/doxygen/norm/html/classmcl__timer__handler__inherit__graph.dot new file mode 100644 index 0000000..17095d7 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__timer__handler__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node146 [label="mcl_timer_handler",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node146 -> Node147 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node147 [label="mcl_rx_ctrl",height=0.2,width=0.4,color="black",URL="$classmcl__rx__ctrl.html"]; + Node146 -> Node148 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node148 [label="mcl_tx_ctrl",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__coll__graph.dot b/doc/doxygen/norm/html/classmcl__tx__coll__graph.dot new file mode 100644 index 0000000..7cea3b1 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__coll__graph.dot @@ -0,0 +1,14 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node151 [label="mcl_tx",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node152 -> Node151 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu_head",fontname="Helvetica"]; + Node152 [label="mcl_adu",height=0.2,width=0.4,color="black",URL="$classmcl__adu.html"]; + Node152 -> Node152 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node153 -> Node152 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="addr",fontname="Helvetica"]; + Node153 [label="mcl_addr",height=0.2,width=0.4,color="black",URL="$classmcl__addr.html"]; + Node154 -> Node152 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node154 [label="mcl_block",height=0.2,width=0.4,color="red",URL="$classmcl__block.html"]; + Node152 -> Node154 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__ctrl__FLUSH__DONE__tevent__coll__graph.dot b/doc/doxygen/norm/html/classmcl__tx__ctrl__FLUSH__DONE__tevent__coll__graph.dot new file mode 100644 index 0000000..2df270a --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__ctrl__FLUSH__DONE__tevent__coll__graph.dot @@ -0,0 +1,9 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node169 [label="mcl_tx_ctrl_FLUSH_DONE_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node170 -> Node169 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node170 [label="mcl_tx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl__tevent.html"]; + Node170 -> Node170 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__ctrl__FLUSH__DONE__tevent__inherit__graph.dot b/doc/doxygen/norm/html/classmcl__tx__ctrl__FLUSH__DONE__tevent__inherit__graph.dot new file mode 100644 index 0000000..5bca1fe --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__ctrl__FLUSH__DONE__tevent__inherit__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node167 [label="mcl_tx_ctrl_FLUSH_DONE_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node168 -> Node167 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node168 [label="mcl_tx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl__tevent.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__ctrl__RETX__DONE__tevent__coll__graph.dot b/doc/doxygen/norm/html/classmcl__tx__ctrl__RETX__DONE__tevent__coll__graph.dot new file mode 100644 index 0000000..1c04c15 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__ctrl__RETX__DONE__tevent__coll__graph.dot @@ -0,0 +1,9 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node173 [label="mcl_tx_ctrl_RETX_DONE_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node174 -> Node173 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node174 [label="mcl_tx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl__tevent.html"]; + Node174 -> Node174 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__ctrl__RETX__DONE__tevent__inherit__graph.dot b/doc/doxygen/norm/html/classmcl__tx__ctrl__RETX__DONE__tevent__inherit__graph.dot new file mode 100644 index 0000000..ca81d60 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__ctrl__RETX__DONE__tevent__inherit__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node171 [label="mcl_tx_ctrl_RETX_DONE_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node172 -> Node171 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node172 [label="mcl_tx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl__tevent.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__ctrl__coll__graph.dot b/doc/doxygen/norm/html/classmcl__tx__ctrl__coll__graph.dot new file mode 100644 index 0000000..51dcf01 --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__ctrl__coll__graph.dot @@ -0,0 +1,21 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node159 [label="mcl_tx_ctrl",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node160 -> Node159 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node160 [label="mcl_timer_handler",height=0.2,width=0.4,color="black",URL="$classmcl__timer__handler.html"]; + Node161 -> Node159 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="RETX_DONE_tevent_head\nFLUSH_DONE_tevent_head",fontname="Helvetica"]; + Node161 [label="mcl_tx_ctrl_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl__tevent.html"]; + Node161 -> Node161 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node162 -> Node159 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="blk_of_last_du",fontname="Helvetica"]; + Node162 [label="mcl_block",height=0.2,width=0.4,color="black",URL="$classmcl__block.html"]; + Node163 -> Node162 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="adu",fontname="Helvetica"]; + Node163 [label="mcl_adu",height=0.2,width=0.4,color="red",URL="$classmcl__adu.html"]; + Node163 -> Node163 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; + Node162 -> Node163 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block_head",fontname="Helvetica"]; + Node165 -> Node162 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head\nfec_du_head",fontname="Helvetica"]; + Node165 [label="mcl_du",height=0.2,width=0.4,color="red",URL="$classmcl__du.html"]; + Node165 -> Node165 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext\ntx_next\ntx_prev",fontname="Helvetica"]; + Node162 -> Node165 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__ctrl__inherit__graph.dot b/doc/doxygen/norm/html/classmcl__tx__ctrl__inherit__graph.dot new file mode 100644 index 0000000..4f0627d --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__ctrl__inherit__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node157 [label="mcl_tx_ctrl",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node158 -> Node157 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node158 [label="mcl_timer_handler",height=0.2,width=0.4,color="black",URL="$classmcl__timer__handler.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__ctrl__tevent__coll__graph.dot b/doc/doxygen/norm/html/classmcl__tx__ctrl__tevent__coll__graph.dot new file mode 100644 index 0000000..ceddaee --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__ctrl__tevent__coll__graph.dot @@ -0,0 +1,7 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node178 [label="mcl_tx_ctrl_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node178 -> Node178 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__ctrl__tevent__inherit__graph.dot b/doc/doxygen/norm/html/classmcl__tx__ctrl__tevent__inherit__graph.dot new file mode 100644 index 0000000..31d778d --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__ctrl__tevent__inherit__graph.dot @@ -0,0 +1,10 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node175 [label="mcl_tx_ctrl_tevent",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node175 -> Node176 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node176 [label="mcl_tx_ctrl_FLUSH_DONE_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl__FLUSH__DONE__tevent.html"]; + Node175 -> Node177 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node177 [label="mcl_tx_ctrl_RETX_DONE_tevent",height=0.2,width=0.4,color="black",URL="$classmcl__tx__ctrl__RETX__DONE__tevent.html"]; +} diff --git a/doc/doxygen/norm/html/classmcl__tx__window__coll__graph.dot b/doc/doxygen/norm/html/classmcl__tx__window__coll__graph.dot new file mode 100644 index 0000000..d75995b --- /dev/null +++ b/doc/doxygen/norm/html/classmcl__tx__window__coll__graph.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node182 [label="mcl_tx_window",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node183 -> Node182 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_list_head\nhp_du_list_head\nhp_du_list_snd_max\ndu_list_snd_max",fontname="Helvetica"]; + Node183 [label="mcl_du",height=0.2,width=0.4,color="black",URL="$classmcl__du.html"]; + Node184 -> Node183 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="pkt",fontname="Helvetica"]; + Node184 [label="mcl_rx_pkt",height=0.2,width=0.4,color="black",URL="$classmcl__rx__pkt.html"]; + Node183 -> Node183 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="prev\nnext\ntx_next\ntx_prev",fontname="Helvetica"]; + Node185 -> Node183 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="block",fontname="Helvetica"]; + Node185 [label="mcl_block",height=0.2,width=0.4,color="black",URL="$classmcl__block.html"]; + Node183 -> Node185 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="du_head\nfec_du_head",fontname="Helvetica"]; + Node185 -> Node182 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="blist_head\nblist_snd_una\nblist_snd_max\nblist_tail",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/classtx__buffer__mgmt__coll__graph.dot b/doc/doxygen/norm/html/classtx__buffer__mgmt__coll__graph.dot new file mode 100644 index 0000000..bc78053 --- /dev/null +++ b/doc/doxygen/norm/html/classtx__buffer__mgmt__coll__graph.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node235 [label="tx_buffer_mgmt",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node236 -> Node235 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="stats",fontname="Helvetica"]; + Node236 [label="tx_buffer_stats_t",height=0.2,width=0.4,color="black",URL="$structtx__buffer__stats__t.html"]; +} diff --git a/doc/doxygen/norm/html/doxygen.css b/doc/doxygen/norm/html/doxygen.css new file mode 100644 index 0000000..0564e82 --- /dev/null +++ b/doc/doxygen/norm/html/doxygen.css @@ -0,0 +1,160 @@ +H1 { + text-align: center; + font-family: Arial, Helvetica, sans-serif; +} +H2 { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +CAPTION { font-weight: bold } +DIV.qindex { width: 100%; + background-color: #eeeeff; + border: 4px solid #eeeeff; + text-align: center; + margin-bottom: 2px +} +A.qindex { text-decoration: none; font-weight: bold; } +A.qindex:hover { text-decoration: none; background-color: #ddddff } +A.qindexHL { text-decoration: none; font-weight: bold; + background-color: #6666cc; + color: #ffffff + } +A.qindexHL:hover { text-decoration: none; background-color: #6666cc } +A.qindexRef { text-decoration: none; font-weight: bold; } +A.qindexRef:hover { text-decoration: none; background-color: #ddddff } +A.qindexRefHL { text-decoration: none; font-weight: bold; + background-color: #6666cc; + color: #ffffff + } +A.qindexRefHL:hover { text-decoration: none; background-color: #6666cc } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code { text-decoration: none; font-weight: normal; color: #4444ee } +A.codeRef { font-weight: normal; color: #4444ee } +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +DIV.fragment { + width: 98%; + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + padding-left: 4px; + margin: 4px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } +TD.md { background-color: #f2f2ff; font-weight: bold; } +TD.mdname1 { background-color: #f2f2ff; font-weight: bold; color: #602020; } +TD.mdname { background-color: #f2f2ff; font-weight: bold; color: #602020; width: 600px; } +DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } +DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } +BODY { + background: white; + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #eeeeff; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} +TD.indexvalue { + background-color: #eeeeff; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdTable { + border: 1px solid #868686; + background-color: #f2f2ff; +} +.mdRow { + padding: 8px 20px; +} +.mdescLeft { + font-size: smaller; + font-family: Arial, Helvetica, sans-serif; + background-color: #FAFAFA; + padding-left: 8px; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + font-size: smaller; + font-family: Arial, Helvetica, sans-serif; + font-style: italic; + background-color: #FAFAFA; + padding-left: 4px; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; + padding-bottom: 0px; + padding-right: 8px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-style: solid; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-family: Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; +} +.memItemRight { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-style: solid; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-family: Geneva, Arial, Helvetica, sans-serif; + font-size: 13px; +} diff --git a/doc/doxygen/norm/html/doxygen.png b/doc/doxygen/norm/html/doxygen.png new file mode 100644 index 0000000..96ae72c Binary files /dev/null and b/doc/doxygen/norm/html/doxygen.png differ diff --git a/doc/doxygen/norm/html/graph_legend.dot b/doc/doxygen/norm/html/graph_legend.dot new file mode 100644 index 0000000..5420927 --- /dev/null +++ b/doc/doxygen/norm/html/graph_legend.dot @@ -0,0 +1,22 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node9 [shape="box",label="Inherited",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",style="filled" fontcolor="white"]; + Node10 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node10 [shape="box",label="PublicBase",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classPublicBase.html"]; + Node11 -> Node10 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node11 [shape="box",label="Truncated",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="red",URL="$classTruncated.html"]; + Node13 -> Node9 [dir=back,color="darkgreen",fontsize=10,style="solid",fontname="Helvetica"]; + Node13 [shape="box",label="ProtectedBase",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classProtectedBase.html"]; + Node14 -> Node9 [dir=back,color="firebrick4",fontsize=10,style="solid",fontname="Helvetica"]; + Node14 [shape="box",label="PrivateBase",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classPrivateBase.html"]; + Node15 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node15 [shape="box",label="Undocumented",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="grey75"]; + Node16 -> Node9 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node16 [shape="box",label="Templ< int >",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classTempl.html"]; + Node17 -> Node16 [dir=back,color="orange",fontsize=10,style="dashed",label="< int >",fontname="Helvetica"]; + Node17 [shape="box",label="Templ< T >",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classTempl.html"]; + Node18 -> Node9 [dir=back,color="darkorchid3",fontsize=10,style="dashed",label="m_usedClass",fontname="Helvetica"]; + Node18 [shape="box",label="Used",fontsize=10,height=0.2,width=0.4,fontname="Helvetica",color="black",URL="$classUsed.html"]; +} diff --git a/doc/doxygen/norm/html/inherit__graph__0.dot b/doc/doxygen/norm/html/inherit__graph__0.dot new file mode 100644 index 0000000..97c733e --- /dev/null +++ b/doc/doxygen/norm/html/inherit__graph__0.dot @@ -0,0 +1,7 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + rankdir=LR; + Node63 [label="fec_parms",height=0.2,width=0.4,color="black",URL="$structfec__parms.html"]; +} diff --git a/doc/doxygen/norm/html/mcl_8cpp__incl.dot b/doc/doxygen/norm/html/mcl_8cpp__incl.dot new file mode 100644 index 0000000..72e7d64 --- /dev/null +++ b/doc/doxygen/norm/html/mcl_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node279 [label="mcl.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node280 -> Node279 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node280 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node281 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node281 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node282 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node282 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node283 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node283 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node284 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node284 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node285 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node285 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node286 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node286 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node287 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node287 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node288 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node288 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node289 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node289 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node290 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node290 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node291 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node291 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node292 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node292 [label="new",height=0.2,width=0.4,color="grey75"]; + Node293 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node293 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node294 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node294 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node295 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node295 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node296 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node296 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node297 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node297 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node298 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node298 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node299 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node299 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node300 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node300 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node301 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node301 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node302 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node302 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node303 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node303 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node304 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node304 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node305 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node305 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node306 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node306 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node307 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node307 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node308 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node308 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node309 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node309 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node310 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node310 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node311 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node311 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node312 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node312 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node313 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node313 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node314 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node314 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node315 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node315 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node316 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node316 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node317 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node317 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node318 -> Node317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node318 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node319 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node319 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node320 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node320 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node321 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node321 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node322 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node322 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node323 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node323 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node321 -> Node323 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node324 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node324 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node325 -> Node324 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node325 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node326 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node326 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node327 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node327 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node328 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node328 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node329 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node329 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node330 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node330 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node318 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node331 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node331 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node333 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node333 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node334 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node334 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node335 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node335 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node337 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node337 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node338 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node338 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node339 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node339 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node340 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node340 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node341 -> Node321 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node341 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node322 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node323 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node325 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node324 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node326 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node327 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node328 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node329 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node330 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node318 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node331 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node333 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node334 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node335 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node337 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node338 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node339 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node340 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node341 -> Node280 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl_8h__dep__incl.dot new file mode 100644 index 0000000..e22fe0a --- /dev/null +++ b/doc/doxygen/norm/html/mcl_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node344 [label="mcl.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node345 -> Node344 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node345 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__addr_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__addr_8h__dep__incl.dot new file mode 100644 index 0000000..f897001 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__addr_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node3 [label="mcl_addr.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node4 -> Node3 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node4 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__adu_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__adu_8cpp__incl.dot new file mode 100644 index 0000000..ecb90ca --- /dev/null +++ b/doc/doxygen/norm/html/mcl__adu_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node373 [label="mcl_adu.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node374 -> Node373 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node374 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node375 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node375 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node376 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node376 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node377 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node377 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node378 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node378 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node379 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node379 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node380 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node380 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node381 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node381 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node382 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node382 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node383 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node383 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node384 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node384 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node385 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node385 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node386 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node386 [label="new",height=0.2,width=0.4,color="grey75"]; + Node387 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node387 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node388 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node388 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node389 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node389 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node390 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node390 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node391 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node391 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node392 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node392 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node393 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node393 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node394 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node394 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node395 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node395 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node396 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node396 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node397 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node397 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node398 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node398 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node399 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node399 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node400 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node400 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node401 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node401 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node402 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node402 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node403 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node403 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node404 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node404 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node405 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node405 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node406 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node406 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node407 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node407 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node408 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node408 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node409 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node409 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node410 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node410 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node411 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node411 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node412 -> Node411 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node412 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node413 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node413 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node414 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node414 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node415 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node415 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node416 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node416 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node417 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node417 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node415 -> Node417 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node418 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node418 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node419 -> Node418 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node419 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node420 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node420 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node421 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node421 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node422 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node422 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node423 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node423 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node424 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node424 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node412 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node425 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node425 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node427 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node427 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node428 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node428 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node429 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node429 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node431 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node431 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node432 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node432 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node433 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node433 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node434 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node434 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node435 -> Node415 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node435 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node416 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node417 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node419 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node418 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node420 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node421 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node422 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node423 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node424 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node412 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node425 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node427 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node428 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node429 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node431 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node432 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node433 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node434 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node435 -> Node374 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__adu_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__adu_8h__dep__incl.dot new file mode 100644 index 0000000..8d0baad --- /dev/null +++ b/doc/doxygen/norm/html/mcl__adu_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node439 [label="mcl_adu.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node440 -> Node439 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node440 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__adu_8h__incl.dot b/doc/doxygen/norm/html/mcl__adu_8h__incl.dot new file mode 100644 index 0000000..09631fa --- /dev/null +++ b/doc/doxygen/norm/html/mcl__adu_8h__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node437 [label="mcl_adu.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node438 -> Node437 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node438 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__async__fec_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__async__fec_8cpp__incl.dot new file mode 100644 index 0000000..0754b27 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__async__fec_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node466 [label="mcl_async_fec.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node467 -> Node466 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node467 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node468 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node468 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node469 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node469 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node470 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node470 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node471 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node471 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node472 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node472 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node473 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node473 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node474 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node474 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node475 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node475 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node476 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node476 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node477 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node477 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node478 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node478 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node479 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node479 [label="new",height=0.2,width=0.4,color="grey75"]; + Node480 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node480 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node481 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node481 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node482 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node482 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node483 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node483 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node484 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node484 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node485 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node485 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node486 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node486 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node487 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node487 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node488 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node488 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node489 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node489 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node490 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node490 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node491 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node491 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node492 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node492 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node493 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node493 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node494 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node494 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node495 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node495 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node496 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node496 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node497 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node497 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node498 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node498 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node499 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node499 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node500 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node500 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node501 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node501 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node502 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node502 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node503 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node503 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node504 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node504 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node505 -> Node504 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node505 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node506 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node506 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node507 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node507 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node508 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node508 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node509 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node509 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node510 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node510 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node508 -> Node510 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node511 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node511 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node512 -> Node511 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node512 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node513 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node513 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node514 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node514 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node515 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node515 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node516 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node516 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node517 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node517 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node505 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node518 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node518 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node520 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node520 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node521 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node521 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node522 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node522 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node524 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node524 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node525 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node525 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node526 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node526 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node527 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node527 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node528 -> Node508 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node528 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node509 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node510 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node512 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node511 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node513 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node514 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node515 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node516 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node517 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node505 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node518 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node520 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node521 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node522 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node524 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node525 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node526 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node527 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node528 -> Node467 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__block_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__block_8cpp__incl.dot new file mode 100644 index 0000000..eed75d6 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__block_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node532 [label="mcl_block.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node533 -> Node532 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node533 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node534 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node534 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node535 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node535 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node536 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node536 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node537 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node537 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node538 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node538 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node539 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node539 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node540 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node540 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node541 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node541 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node542 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node542 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node543 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node543 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node544 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node544 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node545 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node545 [label="new",height=0.2,width=0.4,color="grey75"]; + Node546 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node546 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node547 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node547 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node548 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node548 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node549 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node549 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node550 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node550 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node551 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node551 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node552 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node552 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node553 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node553 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node554 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node554 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node555 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node555 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node556 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node556 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node557 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node557 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node558 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node558 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node559 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node559 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node560 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node560 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node561 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node561 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node562 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node562 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node563 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node563 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node564 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node564 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node565 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node565 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node566 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node566 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node567 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node567 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node568 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node568 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node569 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node569 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node570 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node570 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node571 -> Node570 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node571 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node572 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node572 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node573 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node573 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node574 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node574 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node575 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node575 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node576 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node576 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node574 -> Node576 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node577 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node577 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node578 -> Node577 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node578 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node579 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node579 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node580 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node580 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node581 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node581 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node582 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node582 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node583 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node583 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node571 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node584 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node584 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node586 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node586 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node587 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node587 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node588 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node588 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node590 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node590 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node591 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node591 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node592 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node592 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node593 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node593 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node594 -> Node574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node594 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node575 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node576 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node578 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node577 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node579 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node580 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node581 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node582 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node583 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node571 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node584 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node586 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node587 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node588 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node590 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node591 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node592 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node593 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node594 -> Node533 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__block_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__block_8h__dep__incl.dot new file mode 100644 index 0000000..82c1f22 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__block_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node597 [label="mcl_block.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node598 -> Node597 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node598 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__cb_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__cb_8cpp__incl.dot new file mode 100644 index 0000000..5954299 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__cb_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node624 [label="mcl_cb.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node625 -> Node624 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node625 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node626 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node626 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node627 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node627 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node628 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node628 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node629 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node629 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node630 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node630 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node631 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node631 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node632 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node632 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node633 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node633 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node634 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node634 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node635 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node635 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node636 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node636 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node637 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node637 [label="new",height=0.2,width=0.4,color="grey75"]; + Node638 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node638 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node639 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node639 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node640 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node640 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node641 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node641 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node642 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node642 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node643 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node643 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node644 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node644 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node645 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node645 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node646 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node646 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node647 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node647 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node648 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node648 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node649 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node649 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node650 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node650 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node651 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node651 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node652 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node652 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node653 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node653 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node654 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node654 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node655 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node655 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node656 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node656 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node657 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node657 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node658 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node658 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node659 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node659 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node660 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node660 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node661 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node661 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node662 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node662 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node663 -> Node662 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node663 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node664 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node664 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node665 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node665 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node666 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node666 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node667 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node667 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node668 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node668 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node666 -> Node668 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node669 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node669 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node670 -> Node669 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node670 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node671 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node671 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node672 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node672 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node673 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node673 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node674 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node674 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node675 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node675 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node663 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node676 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node676 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node678 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node678 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node679 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node679 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node680 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node680 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node682 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node682 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node683 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node683 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node684 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node684 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node685 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node685 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node686 -> Node666 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node686 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node667 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node668 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node670 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node669 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node671 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node672 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node673 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node674 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node675 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node663 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node676 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node678 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node679 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node680 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node682 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node683 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node684 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node685 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node686 -> Node625 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__cb_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__cb_8h__dep__incl.dot new file mode 100644 index 0000000..1850ede --- /dev/null +++ b/doc/doxygen/norm/html/mcl__cb_8h__dep__incl.dot @@ -0,0 +1,12 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node710 [label="mcl_cb.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node711 -> Node710 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node711 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; + Node737 -> Node710 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node737 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node710 -> Node737 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node711 -> Node737 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__cb_8h__incl.dot b/doc/doxygen/norm/html/mcl__cb_8h__incl.dot new file mode 100644 index 0000000..e57eefd --- /dev/null +++ b/doc/doxygen/norm/html/mcl__cb_8h__incl.dot @@ -0,0 +1,46 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node688 [label="mcl_cb.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node689 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node689 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node690 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node690 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node688 -> Node690 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node691 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node691 [label="mcl_timer.h",height=0.2,width=0.4,color="red",URL="$mcl__timer_8h.html"]; + Node693 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node693 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node694 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node694 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node695 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node695 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node696 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node696 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node697 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node697 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node698 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node698 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node699 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node699 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node701 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node701 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node702 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node702 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node703 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node703 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node704 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node704 [label="mcl_group_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__group__mgmt_8h.html"]; + Node689 -> Node704 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node705 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node705 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node706 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node706 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node707 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node707 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node708 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node708 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node709 -> Node688 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node709 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__debug_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__debug_8h__dep__incl.dot new file mode 100644 index 0000000..5b04654 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__debug_8h__dep__incl.dot @@ -0,0 +1,10 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node37 [label="mcl_debug.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node38 -> Node37 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node38 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; + Node64 -> Node37 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node64 [label="rse_fec.cpp",height=0.2,width=0.4,color="black",URL="$rse__fec_8cpp.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__du_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__du_8cpp__incl.dot new file mode 100644 index 0000000..210bffa --- /dev/null +++ b/doc/doxygen/norm/html/mcl__du_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node738 [label="mcl_du.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node739 -> Node738 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node739 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node740 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node740 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node741 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node741 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node742 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node742 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node743 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node743 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node744 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node744 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node745 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node745 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node746 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node746 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node747 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node747 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node748 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node748 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node749 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node749 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node750 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node750 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node751 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node751 [label="new",height=0.2,width=0.4,color="grey75"]; + Node752 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node752 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node753 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node753 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node754 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node754 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node755 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node755 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node756 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node756 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node757 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node757 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node758 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node758 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node759 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node759 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node760 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node760 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node761 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node761 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node762 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node762 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node763 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node763 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node764 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node764 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node765 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node765 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node766 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node766 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node767 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node767 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node768 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node768 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node769 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node769 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node770 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node770 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node771 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node771 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node772 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node772 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node773 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node773 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node774 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node774 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node775 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node775 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node776 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node776 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node777 -> Node776 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node777 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node778 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node778 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node779 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node779 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node780 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node780 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node781 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node781 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node782 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node782 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node780 -> Node782 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node783 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node783 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node784 -> Node783 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node784 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node785 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node785 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node786 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node786 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node787 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node787 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node788 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node788 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node789 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node789 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node777 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node790 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node790 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node792 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node792 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node793 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node793 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node794 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node794 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node796 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node796 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node797 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node797 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node798 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node798 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node799 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node799 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node800 -> Node780 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node800 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node781 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node782 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node784 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node783 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node785 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node786 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node787 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node788 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node789 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node777 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node790 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node792 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node793 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node794 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node796 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node797 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node798 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node799 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node800 -> Node739 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__du_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__du_8h__dep__incl.dot new file mode 100644 index 0000000..c65a119 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__du_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node803 [label="mcl_du.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node804 -> Node803 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node804 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__fec_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__fec_8cpp__incl.dot new file mode 100644 index 0000000..e3b7e93 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__fec_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node830 [label="mcl_fec.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node831 -> Node830 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node831 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node832 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node832 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node833 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node833 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node834 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node834 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node835 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node835 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node836 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node836 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node837 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node837 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node838 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node838 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node839 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node839 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node840 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node840 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node841 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node841 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node842 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node842 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node843 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node843 [label="new",height=0.2,width=0.4,color="grey75"]; + Node844 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node844 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node845 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node845 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node846 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node846 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node847 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node847 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node848 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node848 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node849 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node849 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node850 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node850 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node851 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node851 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node852 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node852 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node853 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node853 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node854 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node854 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node855 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node855 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node856 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node856 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node857 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node857 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node858 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node858 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node859 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node859 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node860 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node860 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node861 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node861 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node862 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node862 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node863 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node863 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node864 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node864 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node865 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node865 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node866 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node866 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node867 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node867 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node868 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node868 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node869 -> Node868 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node869 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node870 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node870 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node871 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node871 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node872 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node872 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node873 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node873 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node874 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node874 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node872 -> Node874 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node875 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node875 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node876 -> Node875 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node876 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node877 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node877 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node878 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node878 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node879 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node879 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node880 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node880 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node881 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node881 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node869 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node882 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node882 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node884 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node884 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node885 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node885 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node886 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node886 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node888 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node888 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node889 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node889 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node890 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node890 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node891 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node891 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node892 -> Node872 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node892 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node873 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node874 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node876 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node875 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node877 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node878 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node879 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node880 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node881 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node869 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node882 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node884 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node885 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node886 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node888 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node889 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node890 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node891 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node892 -> Node831 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__fec_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__fec_8h__dep__incl.dot new file mode 100644 index 0000000..637ceaf --- /dev/null +++ b/doc/doxygen/norm/html/mcl__fec_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node895 [label="mcl_fec.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node896 -> Node895 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node896 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node897 -> Node896 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node897 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node923 -> Node896 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node923 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node896 -> Node923 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node897 -> Node923 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node897 -> Node895 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__fsm_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__fsm_8cpp__incl.dot new file mode 100644 index 0000000..7884c4d --- /dev/null +++ b/doc/doxygen/norm/html/mcl__fsm_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node924 [label="mcl_fsm.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node925 -> Node924 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node925 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node926 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node926 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node927 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node927 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node928 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node928 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node929 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node929 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node930 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node930 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node931 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node931 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node932 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node932 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node933 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node933 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node934 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node934 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node935 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node935 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node936 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node936 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node937 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node937 [label="new",height=0.2,width=0.4,color="grey75"]; + Node938 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node938 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node939 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node939 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node940 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node940 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node941 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node941 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node942 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node942 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node943 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node943 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node944 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node944 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node945 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node945 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node946 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node946 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node947 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node947 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node948 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node948 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node949 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node949 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node950 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node950 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node951 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node951 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node952 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node952 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node953 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node953 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node954 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node954 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node955 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node955 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node956 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node956 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node957 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node957 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node958 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node958 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node959 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node959 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node960 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node960 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node961 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node961 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node962 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node962 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node963 -> Node962 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node963 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node964 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node964 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node965 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node965 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node966 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node966 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node967 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node967 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node968 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node968 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node966 -> Node968 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node969 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node969 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node970 -> Node969 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node970 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node971 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node971 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node972 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node972 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node973 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node973 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node974 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node974 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node975 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node975 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node963 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node976 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node976 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node978 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node978 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node979 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node979 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node980 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node980 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node982 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node982 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node983 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node983 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node984 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node984 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node985 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node985 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node986 -> Node966 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node986 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node967 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node968 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node970 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node969 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node971 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node972 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node973 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node974 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node975 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node963 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node976 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node978 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node979 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node980 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node982 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node983 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node984 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node985 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node986 -> Node925 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__fsm_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__fsm_8h__dep__incl.dot new file mode 100644 index 0000000..551cd86 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__fsm_8h__dep__incl.dot @@ -0,0 +1,12 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1010 [label="mcl_fsm.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1011 -> Node1010 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1011 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node1012 -> Node1011 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1012 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1010 -> Node1011 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1012 -> Node1010 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__fsm_8h__incl.dot b/doc/doxygen/norm/html/mcl__fsm_8h__incl.dot new file mode 100644 index 0000000..2162d96 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__fsm_8h__incl.dot @@ -0,0 +1,46 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node988 [label="mcl_fsm.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node989 -> Node988 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node989 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node990 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node990 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node988 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node991 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node991 [label="mcl_timer.h",height=0.2,width=0.4,color="red",URL="$mcl__timer_8h.html"]; + Node993 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node993 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node994 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node994 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node995 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node995 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node996 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node996 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node997 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node997 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node998 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node998 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node999 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node999 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1001 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1001 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1002 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1002 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1003 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1003 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1004 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1004 [label="mcl_group_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__group__mgmt_8h.html"]; + Node990 -> Node1004 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1005 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1005 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1006 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1006 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1007 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1007 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1008 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1008 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1009 -> Node989 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1009 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__group__mgmt_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__group__mgmt_8cpp__incl.dot new file mode 100644 index 0000000..db2e4d2 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__group__mgmt_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1038 [label="mcl_group_mgmt.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1039 -> Node1038 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1039 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1040 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1040 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1041 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1041 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1042 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1042 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1043 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1043 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1044 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1044 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1045 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1045 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1046 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1046 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1047 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1047 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1048 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1048 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1049 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1049 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1050 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1050 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1051 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1051 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1052 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1052 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1053 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1053 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1054 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1054 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1055 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1055 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1056 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1056 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1057 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1057 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1058 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1058 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1059 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1059 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1060 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1060 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1061 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1061 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1062 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1062 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1063 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1063 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1064 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1064 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1065 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1065 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1066 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1066 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1067 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1067 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1068 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1068 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1069 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1069 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1070 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1070 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1071 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1071 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1072 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1072 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1073 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1073 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1074 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1074 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1075 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1075 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1076 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1076 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1077 -> Node1076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1077 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1078 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1078 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1079 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1079 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1080 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1080 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1081 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1081 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1082 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1082 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1080 -> Node1082 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1083 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1083 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1084 -> Node1083 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1084 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1085 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1085 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1086 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1086 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1087 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1087 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1088 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1088 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1089 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1089 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1077 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1090 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1090 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1092 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1092 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1093 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1093 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1094 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1094 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1096 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1096 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1097 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1097 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1098 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1098 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1099 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1099 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1100 -> Node1080 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1100 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1081 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1082 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1084 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1083 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1085 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1086 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1087 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1088 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1089 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1077 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1090 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1092 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1093 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1094 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1096 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1097 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1098 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1099 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1100 -> Node1039 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__group__mgmt_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__group__mgmt_8h__dep__incl.dot new file mode 100644 index 0000000..e17eb68 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__group__mgmt_8h__dep__incl.dot @@ -0,0 +1,14 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1104 [label="mcl_group_mgmt.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1105 -> Node1104 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1105 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node1106 -> Node1105 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1106 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; + Node1132 -> Node1105 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1132 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1105 -> Node1132 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1106 -> Node1132 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__group__mgmt_8h__incl.dot b/doc/doxygen/norm/html/mcl__group__mgmt_8h__incl.dot new file mode 100644 index 0000000..ec104b5 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__group__mgmt_8h__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1102 [label="mcl_group_mgmt.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1103 -> Node1102 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1103 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__includes_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__includes_8h__dep__incl.dot new file mode 100644 index 0000000..236a73d --- /dev/null +++ b/doc/doxygen/norm/html/mcl__includes_8h__dep__incl.dot @@ -0,0 +1,56 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1195 [label="mcl_includes.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1196 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1196 [label="mcl.cpp",height=0.2,width=0.4,color="black",URL="$mcl_8cpp.html"]; + Node1197 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1197 [label="mcl_adu.cpp",height=0.2,width=0.4,color="black",URL="$mcl__adu_8cpp.html"]; + Node1198 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1198 [label="mcl_async_fec.cpp",height=0.2,width=0.4,color="black",URL="$mcl__async__fec_8cpp.html"]; + Node1199 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1199 [label="mcl_block.cpp",height=0.2,width=0.4,color="black",URL="$mcl__block_8cpp.html"]; + Node1200 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1200 [label="mcl_cb.cpp",height=0.2,width=0.4,color="black",URL="$mcl__cb_8cpp.html"]; + Node1201 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1201 [label="mcl_du.cpp",height=0.2,width=0.4,color="black",URL="$mcl__du_8cpp.html"]; + Node1202 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1202 [label="mcl_fec.cpp",height=0.2,width=0.4,color="black",URL="$mcl__fec_8cpp.html"]; + Node1203 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1203 [label="mcl_fsm.cpp",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8cpp.html"]; + Node1204 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1204 [label="mcl_group_mgmt.cpp",height=0.2,width=0.4,color="black",URL="$mcl__group__mgmt_8cpp.html"]; + Node1205 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1205 [label="mcl_lib.cpp",height=0.2,width=0.4,color="black",URL="$mcl__lib_8cpp.html"]; + Node1206 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1206 [label="mcl_node.cpp",height=0.2,width=0.4,color="black",URL="$mcl__node_8cpp.html"]; + Node1207 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1207 [label="mcl_norm_pkt_mgmt.cpp",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8cpp.html"]; + Node1208 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1208 [label="mcl_periodic_proc.cpp",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8cpp.html"]; + Node1209 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1209 [label="mcl_rx.cpp",height=0.2,width=0.4,color="black",URL="$mcl__rx_8cpp.html"]; + Node1210 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1210 [label="mcl_rx_ctrl.cpp",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8cpp.html"]; + Node1211 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1211 [label="mcl_rx_storage.cpp",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8cpp.html"]; + Node1212 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1212 [label="mcl_rx_thread.cpp",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8cpp.html"]; + Node1213 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1213 [label="mcl_rx_window.cpp",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8cpp.html"]; + Node1214 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1214 [label="mcl_ses_channel.cpp",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8cpp.html"]; + Node1215 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1215 [label="mcl_stats.cpp",height=0.2,width=0.4,color="black",URL="$mcl__stats_8cpp.html"]; + Node1216 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1216 [label="mcl_timer.cpp",height=0.2,width=0.4,color="black",URL="$mcl__timer_8cpp.html"]; + Node1217 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1217 [label="mcl_tx.cpp",height=0.2,width=0.4,color="black",URL="$mcl__tx_8cpp.html"]; + Node1218 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1218 [label="mcl_tx_ctrl.cpp",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8cpp.html"]; + Node1219 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1219 [label="mcl_tx_storage.cpp",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8cpp.html"]; + Node1220 -> Node1195 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1220 [label="mcl_tx_window.cpp",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8cpp.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__includes_8h__incl.dot b/doc/doxygen/norm/html/mcl__includes_8h__incl.dot new file mode 100644 index 0000000..ad4c2d6 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__includes_8h__incl.dot @@ -0,0 +1,148 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1133 [label="mcl_includes.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1134 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1134 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1135 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1135 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1136 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1136 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1137 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1137 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1138 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1138 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1139 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1139 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1140 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1140 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1141 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1141 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1142 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1142 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1143 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1143 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1144 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1144 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1145 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1145 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1146 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1146 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1147 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1147 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1148 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1148 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1149 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1149 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1150 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1150 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1151 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1151 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1152 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1152 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1153 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1153 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1154 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1154 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1155 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1155 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1156 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1156 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1157 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1157 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1158 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1158 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1159 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1159 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1160 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1160 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1161 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1161 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1162 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1162 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1163 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1163 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1164 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1164 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1165 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1165 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1166 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1166 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1167 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1167 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1168 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1168 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1169 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1169 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1170 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1170 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1171 -> Node1170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1171 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1172 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1172 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1173 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1173 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1174 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1174 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node1175 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1175 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1176 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1176 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1174 -> Node1176 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1177 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1177 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1178 -> Node1177 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1178 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1179 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1179 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1180 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1180 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1181 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1181 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1182 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1182 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1183 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1183 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1171 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1184 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1184 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node1186 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1186 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1187 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1187 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1188 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1188 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1189 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1189 [label="mcl_group_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__group__mgmt_8h.html"]; + Node1175 -> Node1189 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1190 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1190 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1191 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1191 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1192 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1192 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1193 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1193 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1194 -> Node1174 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1194 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1175 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1176 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1178 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1177 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1179 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1180 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1181 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1182 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1183 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1171 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1184 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1186 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1187 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1188 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1190 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1191 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1192 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1193 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1194 -> Node1133 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__itime_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__itime_8h__dep__incl.dot new file mode 100644 index 0000000..cb169a2 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__itime_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node68 [label="mcl_itime.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node69 -> Node68 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node69 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__lib_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__lib_8cpp__incl.dot new file mode 100644 index 0000000..a6f8141 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__lib_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1221 [label="mcl_lib.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1222 -> Node1221 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1222 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1223 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1223 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1224 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1224 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1225 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1225 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1226 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1226 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1227 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1227 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1228 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1228 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1229 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1229 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1230 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1230 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1231 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1231 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1232 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1232 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1233 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1233 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1234 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1234 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1235 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1235 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1236 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1236 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1237 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1237 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1238 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1238 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1239 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1239 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1240 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1240 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1241 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1241 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1242 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1242 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1243 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1243 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1244 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1244 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1245 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1245 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1246 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1246 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1247 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1247 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1248 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1248 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1249 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1249 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1250 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1250 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1251 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1251 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1252 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1252 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1253 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1253 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1254 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1254 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1255 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1255 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1256 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1256 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1257 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1257 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1258 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1258 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1259 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1259 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1260 -> Node1259 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1260 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1261 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1261 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1262 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1262 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1263 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1263 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1264 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1264 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1265 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1265 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1263 -> Node1265 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1266 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1266 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1267 -> Node1266 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1267 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1268 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1268 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1269 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1269 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1270 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1270 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1271 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1271 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1272 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1272 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1260 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1273 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1273 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1275 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1275 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1276 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1276 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1277 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1277 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1279 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1279 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1280 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1280 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1281 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1281 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1282 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1282 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1283 -> Node1263 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1283 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1264 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1265 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1267 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1266 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1268 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1269 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1270 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1271 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1272 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1260 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1273 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1275 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1276 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1277 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1279 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1280 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1281 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1282 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1283 -> Node1222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__lib__api_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__lib__api_8h__dep__incl.dot new file mode 100644 index 0000000..a13d71f --- /dev/null +++ b/doc/doxygen/norm/html/mcl__lib__api_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node96 [label="mcl_lib_api.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node97 -> Node96 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node97 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__lib__api__norm_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__lib__api__norm_8h__dep__incl.dot new file mode 100644 index 0000000..6ef48c0 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__lib__api__norm_8h__dep__incl.dot @@ -0,0 +1,13 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1286 [label="mcl_lib_api_norm.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1287 -> Node1286 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1287 [label="mcl_tx.h",height=0.2,width=0.4,color="black",URL="$mcl__tx_8h.html"]; + Node1288 -> Node1287 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1288 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1289 -> Node1288 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1289 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; + Node1289 -> Node1287 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__list_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__list_8h__dep__incl.dot new file mode 100644 index 0000000..6efdfe5 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__list_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node126 [label="mcl_list.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node127 -> Node126 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node127 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__node_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__node_8cpp__incl.dot new file mode 100644 index 0000000..12a6c9f --- /dev/null +++ b/doc/doxygen/norm/html/mcl__node_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1318 [label="mcl_node.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1319 -> Node1318 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1319 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1320 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1320 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1321 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1321 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1322 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1322 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1323 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1323 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1324 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1324 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1325 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1325 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1326 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1326 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1327 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1327 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1328 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1328 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1329 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1329 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1330 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1330 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1331 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1331 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1332 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1332 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1333 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1333 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1334 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1334 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1335 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1335 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1336 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1336 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1337 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1337 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1338 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1338 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1339 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1339 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1340 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1340 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1341 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1341 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1342 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1342 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1343 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1343 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1344 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1344 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1345 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1345 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1346 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1346 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1347 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1347 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1348 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1348 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1349 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1349 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1350 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1350 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1351 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1351 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1352 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1352 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1353 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1353 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1354 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1354 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1355 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1355 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1356 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1356 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1357 -> Node1356 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1357 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1358 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1358 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1359 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1359 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1360 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1360 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1361 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1361 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1362 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1362 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1360 -> Node1362 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1363 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1363 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1364 -> Node1363 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1364 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1365 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1365 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1366 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1366 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1367 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1367 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1368 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1368 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1369 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1369 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1357 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1370 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1370 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1372 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1372 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1373 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1373 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1374 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1374 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1376 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1376 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1377 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1377 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1378 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1378 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1379 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1379 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1380 -> Node1360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1380 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1361 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1362 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1364 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1363 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1365 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1366 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1367 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1368 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1369 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1357 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1370 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1372 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1373 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1374 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1376 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1377 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1378 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1379 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1380 -> Node1319 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__node_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__node_8h__dep__incl.dot new file mode 100644 index 0000000..f9e7f34 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__node_8h__dep__incl.dot @@ -0,0 +1,18 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1383 [label="mcl_node.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1384 -> Node1383 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1384 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node1385 -> Node1384 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1385 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1411 -> Node1384 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1411 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1384 -> Node1411 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1385 -> Node1411 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1412 -> Node1383 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1412 [label="mcl_group_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__group__mgmt_8h.html"]; + Node1384 -> Node1412 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1385 -> Node1383 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__norm__hdr_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__norm__hdr_8h__dep__incl.dot new file mode 100644 index 0000000..431b101 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__norm__hdr_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1414 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1415 -> Node1414 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1415 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__norm__pkt__mgmt_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__norm__pkt__mgmt_8cpp__incl.dot new file mode 100644 index 0000000..3c2441f --- /dev/null +++ b/doc/doxygen/norm/html/mcl__norm__pkt__mgmt_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1441 [label="mcl_norm_pkt_mgmt.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1442 -> Node1441 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1442 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1443 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1443 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1444 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1444 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1445 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1445 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1446 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1446 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1447 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1447 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1448 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1448 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1449 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1449 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1450 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1450 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1451 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1451 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1452 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1452 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1453 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1453 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1454 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1454 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1455 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1455 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1456 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1456 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1457 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1457 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1458 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1458 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1459 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1459 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1460 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1460 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1461 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1461 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1462 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1462 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1463 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1463 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1464 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1464 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1465 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1465 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1466 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1466 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1467 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1467 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1468 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1468 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1469 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1469 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1470 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1470 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1471 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1471 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1472 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1472 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1473 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1473 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1474 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1474 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1475 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1475 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1476 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1476 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1477 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1477 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1478 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1478 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1479 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1479 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1480 -> Node1479 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1480 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1481 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1481 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1482 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1482 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1483 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1483 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1484 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1484 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1485 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1485 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1483 -> Node1485 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1486 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1486 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1487 -> Node1486 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1487 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1488 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1488 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1489 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1489 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1490 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1490 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1491 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1491 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1492 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1492 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1480 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1493 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1493 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1495 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1495 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1496 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1496 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1497 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1497 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1499 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1499 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1500 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1500 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1501 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1501 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1502 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1502 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1503 -> Node1483 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1503 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1484 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1485 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1487 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1486 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1488 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1489 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1490 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1491 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1492 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1480 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1493 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1495 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1496 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1497 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1499 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1500 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1501 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1502 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1503 -> Node1442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__norm__pkt__mgmt_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__norm__pkt__mgmt_8h__dep__incl.dot new file mode 100644 index 0000000..22912a5 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__norm__pkt__mgmt_8h__dep__incl.dot @@ -0,0 +1,18 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1506 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1507 -> Node1506 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1507 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1508 -> Node1507 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1508 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1534 -> Node1506 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1534 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node1508 -> Node1534 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1535 -> Node1534 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1535 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1534 -> Node1535 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1508 -> Node1535 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1508 -> Node1506 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__osdep_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__osdep_8h__dep__incl.dot new file mode 100644 index 0000000..b9d377d --- /dev/null +++ b/doc/doxygen/norm/html/mcl__osdep_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node156 [label="mcl_osdep.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node157 -> Node156 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node157 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__periodic__proc_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__periodic__proc_8cpp__incl.dot new file mode 100644 index 0000000..67cdd1b --- /dev/null +++ b/doc/doxygen/norm/html/mcl__periodic__proc_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1536 [label="mcl_periodic_proc.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1537 -> Node1536 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1537 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1538 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1538 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1539 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1539 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1540 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1540 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1541 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1541 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1542 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1542 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1543 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1543 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1544 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1544 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1545 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1545 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1546 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1546 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1547 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1547 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1548 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1548 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1549 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1549 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1550 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1550 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1551 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1551 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1552 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1552 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1553 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1553 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1554 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1554 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1555 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1555 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1556 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1556 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1557 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1557 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1558 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1558 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1559 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1559 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1560 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1560 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1561 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1561 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1562 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1562 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1563 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1563 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1564 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1564 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1565 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1565 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1566 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1566 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1567 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1567 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1568 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1568 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1569 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1569 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1570 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1570 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1571 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1571 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1572 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1572 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1573 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1573 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1574 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1574 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1575 -> Node1574 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1575 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1576 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1576 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1577 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1577 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1578 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1578 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1579 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1579 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1580 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1580 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1578 -> Node1580 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1581 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1581 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1582 -> Node1581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1582 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1583 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1583 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1584 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1584 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1585 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1585 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1586 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1586 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1587 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1587 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1575 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1588 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1588 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1590 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1590 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1591 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1591 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1592 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1592 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1594 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1594 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1595 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1595 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1596 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1596 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1597 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1597 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1598 -> Node1578 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1598 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1579 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1580 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1582 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1581 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1583 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1584 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1585 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1586 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1587 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1575 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1588 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1590 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1591 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1592 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1594 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1595 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1596 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1597 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1598 -> Node1537 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__periodic__proc_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__periodic__proc_8h__dep__incl.dot new file mode 100644 index 0000000..0632b87 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__periodic__proc_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1601 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1602 -> Node1601 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1602 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node1603 -> Node1602 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1603 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1629 -> Node1602 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1629 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1602 -> Node1629 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1603 -> Node1629 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1603 -> Node1601 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__periodic__timer_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__periodic__timer_8h__dep__incl.dot new file mode 100644 index 0000000..fa4c0eb --- /dev/null +++ b/doc/doxygen/norm/html/mcl__periodic__timer_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node186 [label="mcl_periodic_timer.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node187 -> Node186 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node187 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node188 -> Node187 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node188 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node214 -> Node187 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node214 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node187 -> Node214 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node188 -> Node214 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node188 -> Node186 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__profile_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__profile_8h__dep__incl.dot new file mode 100644 index 0000000..a709a09 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__profile_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1631 [label="mcl_profile.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1632 -> Node1631 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1632 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__rx_8cpp__incl.dot new file mode 100644 index 0000000..276077b --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1658 [label="mcl_rx.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1659 -> Node1658 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1659 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1660 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1660 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1661 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1661 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1662 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1662 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1663 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1663 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1664 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1664 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1665 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1665 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1666 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1666 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1667 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1667 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1668 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1668 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1669 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1669 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1670 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1670 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1671 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1671 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1672 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1672 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1673 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1673 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1674 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1674 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1675 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1675 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1676 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1676 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1677 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1677 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1678 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1678 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1679 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1679 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1680 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1680 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1681 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1681 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1682 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1682 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1683 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1683 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1684 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1684 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1685 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1685 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1686 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1686 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1687 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1687 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1688 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1688 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1689 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1689 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1690 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1690 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1691 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1691 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1692 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1692 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1693 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1693 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1694 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1694 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1695 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1695 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1696 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1696 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1697 -> Node1696 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1697 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1698 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1698 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1699 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1699 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1700 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1700 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1701 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1701 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1702 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1702 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1700 -> Node1702 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1703 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1703 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1704 -> Node1703 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1704 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1705 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1705 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1706 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1706 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1707 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1707 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1708 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1708 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1709 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1709 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1697 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1710 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1710 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1712 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1712 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1713 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1713 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1714 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1714 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1716 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1716 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1717 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1717 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1718 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1718 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1719 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1719 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1720 -> Node1700 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1720 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1701 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1702 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1704 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1703 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1705 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1706 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1707 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1708 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1709 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1697 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1710 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1712 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1713 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1714 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1716 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1717 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1718 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1719 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1720 -> Node1659 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__rx_8h__dep__incl.dot new file mode 100644 index 0000000..7ccd36a --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1723 [label="mcl_rx.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1724 -> Node1723 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1724 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node1725 -> Node1724 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1725 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1751 -> Node1724 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1751 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1724 -> Node1751 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1725 -> Node1751 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1725 -> Node1723 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx__ctrl_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__rx__ctrl_8cpp__incl.dot new file mode 100644 index 0000000..cf3601a --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx__ctrl_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1752 [label="mcl_rx_ctrl.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1753 -> Node1752 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1753 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1754 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1754 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1755 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1755 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1756 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1756 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1757 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1757 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1758 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1758 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1759 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1759 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1760 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1760 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1761 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1761 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1762 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1762 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1763 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1763 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1764 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1764 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1765 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1765 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1766 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1766 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1767 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1767 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1768 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1768 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1769 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1769 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1770 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1770 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1771 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1771 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1772 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1772 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1773 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1773 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1774 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1774 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1775 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1775 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1776 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1776 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1777 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1777 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1778 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1778 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1779 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1779 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1780 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1780 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1781 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1781 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1782 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1782 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1783 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1783 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1784 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1784 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1785 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1785 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1786 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1786 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1787 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1787 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1788 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1788 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1789 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1789 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1790 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1790 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1791 -> Node1790 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1791 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1792 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1792 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1793 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1793 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1794 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1794 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1795 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1795 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1796 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1796 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1794 -> Node1796 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1797 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1797 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1798 -> Node1797 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1798 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1799 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1799 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1800 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1800 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1801 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1801 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1802 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1802 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1803 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1803 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1791 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1804 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1804 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1806 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1806 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1807 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1807 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1808 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1808 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1810 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1810 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1811 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1811 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1812 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1812 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1813 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1813 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1814 -> Node1794 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1814 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1795 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1796 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1798 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1797 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1799 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1800 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1801 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1802 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1803 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1791 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1804 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1806 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1807 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1808 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1810 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1811 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1812 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1813 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1814 -> Node1753 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx__ctrl_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__rx__ctrl_8h__dep__incl.dot new file mode 100644 index 0000000..0c41937 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx__ctrl_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1817 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1818 -> Node1817 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1818 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node1819 -> Node1818 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1819 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1845 -> Node1818 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1845 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1818 -> Node1845 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1819 -> Node1845 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1819 -> Node1817 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx__storage_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__rx__storage_8cpp__incl.dot new file mode 100644 index 0000000..4583698 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx__storage_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1846 [label="mcl_rx_storage.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1847 -> Node1846 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1847 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1848 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1848 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1849 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1849 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1850 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1850 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1851 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1851 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1852 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1852 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1853 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1853 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1854 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1854 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1855 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1855 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1856 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1856 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1857 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1857 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1858 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1858 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1859 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1859 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1860 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1860 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1861 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1861 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1862 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1862 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1863 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1863 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1864 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1864 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1865 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1865 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1866 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1866 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1867 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1867 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1868 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1868 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1869 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1869 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1870 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1870 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1871 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1871 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1872 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1872 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1873 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1873 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1874 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1874 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1875 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1875 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1876 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1876 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1877 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1877 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1878 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1878 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1879 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1879 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1880 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1880 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1881 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1881 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1882 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1882 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1883 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1883 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1884 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1884 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1885 -> Node1884 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1885 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1886 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1886 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1887 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1887 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1888 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1888 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1889 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1889 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1890 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1890 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1888 -> Node1890 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1891 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1891 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1892 -> Node1891 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1892 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1893 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1893 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1894 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1894 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1895 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1895 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1896 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1896 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1897 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1897 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1885 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1898 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1898 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1900 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1900 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1901 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1901 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1902 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1902 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1904 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1904 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1905 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1905 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node1906 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1906 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node1907 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1907 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node1908 -> Node1888 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1908 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1889 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1890 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1892 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1891 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1893 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1894 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1895 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1896 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1897 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1885 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1898 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1900 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1901 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1902 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1904 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1905 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1906 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1907 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1908 -> Node1847 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx__storage_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__rx__storage_8h__dep__incl.dot new file mode 100644 index 0000000..efaa34d --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx__storage_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1911 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1912 -> Node1911 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1912 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node1913 -> Node1912 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1913 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1939 -> Node1912 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1939 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1912 -> Node1939 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1913 -> Node1939 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1913 -> Node1911 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx__thread_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__rx__thread_8cpp__incl.dot new file mode 100644 index 0000000..220280e --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx__thread_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node1940 [label="mcl_rx_thread.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node1941 -> Node1940 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1941 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node1942 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1942 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node1943 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1943 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node1944 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1944 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node1945 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1945 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node1946 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1946 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node1947 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1947 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node1948 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1948 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node1949 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1949 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node1950 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1950 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node1951 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1951 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node1952 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1952 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node1953 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1953 [label="new",height=0.2,width=0.4,color="grey75"]; + Node1954 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1954 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node1955 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1955 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node1956 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1956 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node1957 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1957 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node1958 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1958 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node1959 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1959 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node1960 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1960 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node1961 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1961 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node1962 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1962 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node1963 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1963 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node1964 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1964 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node1965 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1965 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node1966 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1966 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node1967 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1967 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node1968 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1968 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node1969 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1969 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node1970 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1970 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node1971 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1971 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node1972 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1972 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node1973 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1973 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node1974 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1974 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node1975 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1975 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node1976 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1976 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node1977 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1977 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node1978 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1978 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node1979 -> Node1978 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1979 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node1980 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1980 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node1981 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1981 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node1982 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1982 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node1983 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1983 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node1984 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1984 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node1982 -> Node1984 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1985 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1985 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node1986 -> Node1985 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1986 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node1987 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1987 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node1988 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1988 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node1989 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1989 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node1990 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1990 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node1991 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1991 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node1979 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1992 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1992 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node1994 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1994 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node1995 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1995 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node1996 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1996 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node1998 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1998 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node1999 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1999 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node2000 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2000 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node2001 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2001 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node2002 -> Node1982 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2002 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node1983 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1984 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1986 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1985 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1987 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1988 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1989 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1990 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1991 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1979 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1992 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1994 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1995 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1996 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1998 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node1999 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2000 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2001 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2002 -> Node1941 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx__thread_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__rx__thread_8h__dep__incl.dot new file mode 100644 index 0000000..c5980f8 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx__thread_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2005 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2006 -> Node2005 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2006 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node2007 -> Node2006 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2007 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2033 -> Node2006 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2033 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2006 -> Node2033 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2007 -> Node2033 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2007 -> Node2005 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx__window_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__rx__window_8cpp__incl.dot new file mode 100644 index 0000000..a1e2185 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx__window_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2034 [label="mcl_rx_window.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2035 -> Node2034 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2035 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2036 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2036 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node2037 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2037 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node2038 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2038 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node2039 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2039 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node2040 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2040 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node2041 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2041 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node2042 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2042 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node2043 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2043 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node2044 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2044 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node2045 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2045 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node2046 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2046 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node2047 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2047 [label="new",height=0.2,width=0.4,color="grey75"]; + Node2048 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2048 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node2049 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2049 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node2050 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2050 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node2051 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2051 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node2052 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2052 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node2053 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2053 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node2054 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2054 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node2055 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2055 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node2056 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2056 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node2057 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2057 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node2058 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2058 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node2059 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2059 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node2060 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2060 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node2061 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2061 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node2062 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2062 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node2063 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2063 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node2064 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2064 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node2065 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2065 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node2066 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2066 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node2067 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2067 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node2068 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2068 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node2069 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2069 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node2070 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2070 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node2071 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2071 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node2072 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2072 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node2073 -> Node2072 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2073 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node2074 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2074 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node2075 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2075 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node2076 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2076 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node2077 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2077 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node2078 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2078 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2076 -> Node2078 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2079 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2079 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node2080 -> Node2079 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2080 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node2081 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2081 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node2082 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2082 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node2083 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2083 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node2084 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2084 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node2085 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2085 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node2073 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2086 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2086 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node2088 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2088 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node2089 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2089 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node2090 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2090 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node2092 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2092 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node2093 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2093 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node2094 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2094 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node2095 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2095 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node2096 -> Node2076 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2096 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node2077 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2078 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2080 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2079 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2081 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2082 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2083 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2084 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2085 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2073 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2086 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2088 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2089 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2090 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2092 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2093 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2094 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2095 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2096 -> Node2035 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__rx__window_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__rx__window_8h__dep__incl.dot new file mode 100644 index 0000000..31808a1 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__rx__window_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2099 [label="mcl_rx_window.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2100 -> Node2099 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2100 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node2101 -> Node2100 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2101 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2127 -> Node2100 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2127 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2100 -> Node2127 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2101 -> Node2127 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2101 -> Node2099 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__ses__channel_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__ses__channel_8cpp__incl.dot new file mode 100644 index 0000000..ca68f52 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__ses__channel_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2128 [label="mcl_ses_channel.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2129 -> Node2128 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2129 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2130 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2130 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node2131 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2131 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node2132 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2132 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node2133 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2133 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node2134 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2134 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node2135 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2135 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node2136 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2136 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node2137 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2137 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node2138 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2138 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node2139 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2139 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node2140 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2140 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node2141 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2141 [label="new",height=0.2,width=0.4,color="grey75"]; + Node2142 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2142 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node2143 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2143 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node2144 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2144 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node2145 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2145 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node2146 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2146 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node2147 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2147 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node2148 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2148 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node2149 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2149 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node2150 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2150 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node2151 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2151 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node2152 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2152 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node2153 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2153 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node2154 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2154 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node2155 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2155 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node2156 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2156 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node2157 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2157 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node2158 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2158 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node2159 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2159 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node2160 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2160 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node2161 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2161 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node2162 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2162 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node2163 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2163 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node2164 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2164 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node2165 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2165 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node2166 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2166 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node2167 -> Node2166 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2167 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node2168 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2168 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node2169 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2169 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node2170 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2170 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node2171 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2171 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node2172 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2172 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2170 -> Node2172 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2173 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2173 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node2174 -> Node2173 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2174 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node2175 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2175 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node2176 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2176 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node2177 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2177 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node2178 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2178 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node2179 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2179 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node2167 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2180 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2180 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node2182 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2182 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node2183 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2183 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node2184 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2184 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node2186 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2186 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node2187 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2187 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node2188 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2188 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node2189 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2189 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node2190 -> Node2170 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2190 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node2171 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2172 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2174 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2173 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2175 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2176 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2177 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2178 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2179 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2167 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2180 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2182 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2183 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2184 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2186 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2187 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2188 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2189 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2190 -> Node2129 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__ses__channel_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__ses__channel_8h__dep__incl.dot new file mode 100644 index 0000000..abeaa6b --- /dev/null +++ b/doc/doxygen/norm/html/mcl__ses__channel_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2193 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2194 -> Node2193 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2194 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node2195 -> Node2194 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2195 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2221 -> Node2194 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2221 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2194 -> Node2221 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2195 -> Node2221 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2195 -> Node2193 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__stats_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__stats_8cpp__incl.dot new file mode 100644 index 0000000..298fa37 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__stats_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2222 [label="mcl_stats.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2223 -> Node2222 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2223 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2224 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2224 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node2225 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2225 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node2226 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2226 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node2227 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2227 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node2228 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2228 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node2229 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2229 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node2230 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2230 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node2231 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2231 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node2232 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2232 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node2233 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2233 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node2234 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2234 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node2235 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2235 [label="new",height=0.2,width=0.4,color="grey75"]; + Node2236 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2236 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node2237 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2237 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node2238 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2238 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node2239 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2239 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node2240 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2240 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node2241 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2241 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node2242 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2242 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node2243 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2243 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node2244 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2244 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node2245 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2245 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node2246 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2246 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node2247 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2247 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node2248 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2248 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node2249 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2249 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node2250 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2250 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node2251 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2251 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node2252 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2252 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node2253 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2253 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node2254 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2254 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node2255 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2255 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node2256 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2256 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node2257 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2257 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node2258 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2258 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node2259 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2259 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node2260 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2260 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node2261 -> Node2260 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2261 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node2262 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2262 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node2263 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2263 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node2264 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2264 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node2265 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2265 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node2266 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2266 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2264 -> Node2266 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2267 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2267 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node2268 -> Node2267 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2268 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node2269 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2269 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node2270 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2270 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node2271 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2271 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node2272 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2272 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node2273 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2273 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node2261 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2274 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2274 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node2276 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2276 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node2277 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2277 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node2278 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2278 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node2280 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2280 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node2281 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2281 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node2282 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2282 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node2283 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2283 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node2284 -> Node2264 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2284 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node2265 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2266 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2268 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2267 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2269 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2270 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2271 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2272 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2273 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2261 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2274 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2276 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2277 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2278 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2280 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2281 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2282 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2283 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2284 -> Node2223 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__stats_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__stats_8h__dep__incl.dot new file mode 100644 index 0000000..81413eb --- /dev/null +++ b/doc/doxygen/norm/html/mcl__stats_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2287 [label="mcl_stats.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2288 -> Node2287 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2288 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node2289 -> Node2288 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2289 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2315 -> Node2288 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2315 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2288 -> Node2315 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2289 -> Node2315 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2289 -> Node2287 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__timer_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__timer_8cpp__incl.dot new file mode 100644 index 0000000..cfd8423 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__timer_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2316 [label="mcl_timer.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2317 -> Node2316 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2317 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2318 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2318 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node2319 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2319 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node2320 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2320 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node2321 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2321 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node2322 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2322 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node2323 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2323 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node2324 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2324 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node2325 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2325 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node2326 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2326 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node2327 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2327 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node2328 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2328 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node2329 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2329 [label="new",height=0.2,width=0.4,color="grey75"]; + Node2330 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2330 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node2331 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2331 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node2332 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2332 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node2333 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2333 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node2334 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2334 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node2335 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2335 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node2336 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2336 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node2337 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2337 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node2338 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2338 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node2339 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2339 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node2340 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2340 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node2341 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2341 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node2342 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2342 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node2343 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2343 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node2344 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2344 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node2345 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2345 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node2346 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2346 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node2347 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2347 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node2348 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2348 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node2349 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2349 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node2350 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2350 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node2351 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2351 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node2352 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2352 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node2353 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2353 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node2354 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2354 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node2355 -> Node2354 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2355 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node2356 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2356 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node2357 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2357 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node2358 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2358 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node2359 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2359 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node2360 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2360 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2358 -> Node2360 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2361 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2361 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node2362 -> Node2361 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2362 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node2363 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2363 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node2364 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2364 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node2365 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2365 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node2366 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2366 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node2367 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2367 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node2355 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2368 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2368 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node2370 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2370 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node2371 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2371 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node2372 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2372 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node2374 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2374 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node2375 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2375 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node2376 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2376 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node2377 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2377 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node2378 -> Node2358 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2378 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node2359 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2360 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2362 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2361 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2363 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2364 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2365 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2366 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2367 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2355 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2368 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2370 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2371 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2372 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2374 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2375 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2376 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2377 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2378 -> Node2317 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__timer_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__timer_8h__dep__incl.dot new file mode 100644 index 0000000..5b79825 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__timer_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2382 [label="mcl_timer.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2383 -> Node2382 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2383 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node2384 -> Node2383 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2384 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2410 -> Node2383 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2410 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2383 -> Node2410 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2384 -> Node2410 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2384 -> Node2382 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__timer_8h__incl.dot b/doc/doxygen/norm/html/mcl__timer_8h__incl.dot new file mode 100644 index 0000000..5e43124 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__timer_8h__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2380 [label="mcl_timer.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2381 -> Node2380 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2381 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__timer__handler_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__timer__handler_8h__dep__incl.dot new file mode 100644 index 0000000..2bc9d87 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__timer__handler_8h__dep__incl.dot @@ -0,0 +1,14 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2412 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2413 -> Node2412 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2413 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node2414 -> Node2413 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2414 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node2415 -> Node2414 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2415 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2415 -> Node2413 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2415 -> Node2412 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__tx_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__tx_8cpp__incl.dot new file mode 100644 index 0000000..c0d1c7b --- /dev/null +++ b/doc/doxygen/norm/html/mcl__tx_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2442 [label="mcl_tx.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2443 -> Node2442 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2443 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2444 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2444 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node2445 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2445 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node2446 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2446 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node2447 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2447 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node2448 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2448 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node2449 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2449 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node2450 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2450 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node2451 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2451 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node2452 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2452 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node2453 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2453 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node2454 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2454 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node2455 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2455 [label="new",height=0.2,width=0.4,color="grey75"]; + Node2456 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2456 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node2457 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2457 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node2458 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2458 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node2459 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2459 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node2460 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2460 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node2461 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2461 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node2462 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2462 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node2463 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2463 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node2464 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2464 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node2465 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2465 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node2466 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2466 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node2467 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2467 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node2468 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2468 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node2469 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2469 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node2470 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2470 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node2471 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2471 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node2472 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2472 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node2473 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2473 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node2474 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2474 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node2475 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2475 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node2476 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2476 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node2477 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2477 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node2478 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2478 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node2479 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2479 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node2480 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2480 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node2481 -> Node2480 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2481 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node2482 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2482 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node2483 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2483 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node2484 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2484 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node2485 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2485 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node2486 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2486 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2484 -> Node2486 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2487 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2487 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node2488 -> Node2487 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2488 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node2489 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2489 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node2490 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2490 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node2491 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2491 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node2492 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2492 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node2493 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2493 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node2481 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2494 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2494 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node2496 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2496 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node2497 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2497 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node2498 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2498 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node2500 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2500 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node2501 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2501 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node2502 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2502 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node2503 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2503 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node2504 -> Node2484 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2504 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node2485 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2486 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2488 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2487 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2489 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2490 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2491 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2492 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2493 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2481 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2494 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2496 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2497 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2498 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2500 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2501 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2502 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2503 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2504 -> Node2443 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__tx_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__tx_8h__dep__incl.dot new file mode 100644 index 0000000..5a81ef4 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__tx_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2508 [label="mcl_tx.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2509 -> Node2508 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2509 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node2510 -> Node2509 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2510 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2536 -> Node2509 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2536 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2509 -> Node2536 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2510 -> Node2536 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2510 -> Node2508 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__tx_8h__incl.dot b/doc/doxygen/norm/html/mcl__tx_8h__incl.dot new file mode 100644 index 0000000..3f14968 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__tx_8h__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2506 [label="mcl_tx.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2507 -> Node2506 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2507 [label="mcl_lib_api_norm.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api__norm_8h.html"]; +} diff --git a/doc/doxygen/norm/html/mcl__tx__ctrl_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__tx__ctrl_8cpp__incl.dot new file mode 100644 index 0000000..1c0242c --- /dev/null +++ b/doc/doxygen/norm/html/mcl__tx__ctrl_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2539 [label="mcl_tx_ctrl.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2540 -> Node2539 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2540 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2541 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2541 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node2542 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2542 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node2543 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2543 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node2544 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2544 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node2545 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2545 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node2546 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2546 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node2547 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2547 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node2548 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2548 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node2549 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2549 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node2550 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2550 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node2551 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2551 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node2552 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2552 [label="new",height=0.2,width=0.4,color="grey75"]; + Node2553 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2553 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node2554 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2554 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node2555 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2555 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node2556 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2556 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node2557 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2557 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node2558 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2558 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node2559 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2559 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node2560 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2560 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node2561 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2561 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node2562 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2562 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node2563 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2563 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node2564 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2564 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node2565 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2565 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node2566 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2566 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node2567 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2567 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node2568 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2568 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node2569 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2569 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node2570 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2570 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node2571 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2571 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node2572 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2572 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node2573 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2573 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node2574 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2574 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node2575 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2575 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node2576 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2576 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node2577 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2577 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node2578 -> Node2577 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2578 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node2579 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2579 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node2580 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2580 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node2581 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2581 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node2582 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2582 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node2583 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2583 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2581 -> Node2583 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2584 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2584 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node2585 -> Node2584 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2585 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node2586 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2586 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node2587 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2587 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node2588 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2588 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node2589 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2589 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node2590 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2590 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node2578 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2591 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2591 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node2593 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2593 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node2594 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2594 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node2595 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2595 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node2597 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2597 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node2598 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2598 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node2599 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2599 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node2600 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2600 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node2601 -> Node2581 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2601 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node2582 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2583 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2585 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2584 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2586 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2587 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2588 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2589 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2590 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2578 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2591 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2593 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2594 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2595 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2597 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2598 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2599 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2600 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2601 -> Node2540 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__tx__ctrl_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__tx__ctrl_8h__dep__incl.dot new file mode 100644 index 0000000..f407bb6 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__tx__ctrl_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2604 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2605 -> Node2604 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2605 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node2606 -> Node2605 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2606 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2632 -> Node2605 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2632 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2605 -> Node2632 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2606 -> Node2632 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2606 -> Node2604 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__tx__storage_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__tx__storage_8cpp__incl.dot new file mode 100644 index 0000000..70722d0 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__tx__storage_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2633 [label="mcl_tx_storage.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2634 -> Node2633 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2634 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2635 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2635 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node2636 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2636 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node2637 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2637 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node2638 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2638 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node2639 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2639 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node2640 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2640 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node2641 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2641 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node2642 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2642 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node2643 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2643 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node2644 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2644 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node2645 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2645 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node2646 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2646 [label="new",height=0.2,width=0.4,color="grey75"]; + Node2647 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2647 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node2648 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2648 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node2649 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2649 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node2650 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2650 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node2651 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2651 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node2652 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2652 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node2653 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2653 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node2654 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2654 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node2655 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2655 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node2656 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2656 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node2657 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2657 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node2658 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2658 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node2659 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2659 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node2660 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2660 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node2661 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2661 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node2662 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2662 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node2663 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2663 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node2664 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2664 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node2665 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2665 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node2666 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2666 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node2667 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2667 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node2668 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2668 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node2669 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2669 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node2670 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2670 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node2671 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2671 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node2672 -> Node2671 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2672 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node2673 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2673 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node2674 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2674 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node2675 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2675 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node2676 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2676 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node2677 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2677 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2675 -> Node2677 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2678 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2678 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node2679 -> Node2678 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2679 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node2680 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2680 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node2681 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2681 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node2682 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2682 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node2683 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2683 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node2684 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2684 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node2672 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2685 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2685 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node2687 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2687 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node2688 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2688 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node2689 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2689 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node2691 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2691 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node2692 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2692 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node2693 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2693 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node2694 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2694 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node2695 -> Node2675 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2695 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node2676 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2677 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2679 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2678 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2680 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2681 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2682 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2683 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2684 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2672 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2685 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2687 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2688 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2689 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2691 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2692 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2693 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2694 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2695 -> Node2634 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__tx__storage_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__tx__storage_8h__dep__incl.dot new file mode 100644 index 0000000..38720cb --- /dev/null +++ b/doc/doxygen/norm/html/mcl__tx__storage_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2698 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2699 -> Node2698 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2699 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node2700 -> Node2699 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2700 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2726 -> Node2699 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2726 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2699 -> Node2726 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2700 -> Node2726 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2700 -> Node2698 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__tx__window_8cpp__incl.dot b/doc/doxygen/norm/html/mcl__tx__window_8cpp__incl.dot new file mode 100644 index 0000000..6887afd --- /dev/null +++ b/doc/doxygen/norm/html/mcl__tx__window_8cpp__incl.dot @@ -0,0 +1,147 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2727 [label="mcl_tx_window.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2728 -> Node2727 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2728 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2729 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2729 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node2730 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2730 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node2731 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2731 [label="iostream",height=0.2,width=0.4,color="grey75"]; + Node2732 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2732 [label="errno.h",height=0.2,width=0.4,color="grey75"]; + Node2733 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2733 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node2734 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2734 [label="fcntl.h",height=0.2,width=0.4,color="grey75"]; + Node2735 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2735 [label="signal.h",height=0.2,width=0.4,color="grey75"]; + Node2736 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2736 [label="ctype.h",height=0.2,width=0.4,color="grey75"]; + Node2737 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2737 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node2738 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2738 [label="math.h",height=0.2,width=0.4,color="grey75"]; + Node2739 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2739 [label="malloc.h",height=0.2,width=0.4,color="grey75"]; + Node2740 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2740 [label="new",height=0.2,width=0.4,color="grey75"]; + Node2741 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2741 [label="unistd.h",height=0.2,width=0.4,color="grey75"]; + Node2742 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2742 [label="values.h",height=0.2,width=0.4,color="grey75"]; + Node2743 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2743 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node2744 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2744 [label="sys/time.h",height=0.2,width=0.4,color="grey75"]; + Node2745 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2745 [label="sys/wait.h",height=0.2,width=0.4,color="grey75"]; + Node2746 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2746 [label="pthread.h",height=0.2,width=0.4,color="grey75"]; + Node2747 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2747 [label="sys/uio.h",height=0.2,width=0.4,color="grey75"]; + Node2748 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2748 [label="netinet/in.h",height=0.2,width=0.4,color="grey75"]; + Node2749 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2749 [label="sys/socket.h",height=0.2,width=0.4,color="grey75"]; + Node2750 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2750 [label="arpa/inet.h",height=0.2,width=0.4,color="grey75"]; + Node2751 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2751 [label="netdb.h",height=0.2,width=0.4,color="grey75"]; + Node2752 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2752 [label="netinet/ip.h",height=0.2,width=0.4,color="grey75"]; + Node2753 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2753 [label="netinet/udp.h",height=0.2,width=0.4,color="grey75"]; + Node2754 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2754 [label="../common/mcl_osdep.h",height=0.2,width=0.4,color="black",URL="$mcl__osdep_8h.html"]; + Node2755 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2755 [label="mcl_profile.h",height=0.2,width=0.4,color="black",URL="$mcl__profile_8h.html"]; + Node2756 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2756 [label="../common/mcl_lib_api.h",height=0.2,width=0.4,color="black",URL="$mcl__lib__api_8h.html"]; + Node2757 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2757 [label="../common/mcl_version.h",height=0.2,width=0.4,color="black",URL="$mcl__version_8h.html"]; + Node2758 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2758 [label="../common/mcl_addr.h",height=0.2,width=0.4,color="black",URL="$mcl__addr_8h.html"]; + Node2759 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2759 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; + Node2760 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2760 [label="../common/mcl_itime.h",height=0.2,width=0.4,color="black",URL="$mcl__itime_8h.html"]; + Node2761 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2761 [label="../common/mcl_list.h",height=0.2,width=0.4,color="black",URL="$mcl__list_8h.html"]; + Node2762 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2762 [label="../common/rse_fec.h",height=0.2,width=0.4,color="black",URL="$rse__fec_8h.html"]; + Node2763 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2763 [label="mcl.h",height=0.2,width=0.4,color="black",URL="$mcl_8h.html"]; + Node2764 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2764 [label="mcl_norm_hdr.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__hdr_8h.html"]; + Node2765 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2765 [label="mcl_adu.h",height=0.2,width=0.4,color="black",URL="$mcl__adu_8h.html"]; + Node2766 -> Node2765 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2766 [label="mcl_norm_pkt_mgmt.h",height=0.2,width=0.4,color="black",URL="$mcl__norm__pkt__mgmt_8h.html"]; + Node2767 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2767 [label="mcl_du.h",height=0.2,width=0.4,color="black",URL="$mcl__du_8h.html"]; + Node2768 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2768 [label="mcl_block.h",height=0.2,width=0.4,color="black",URL="$mcl__block_8h.html"]; + Node2769 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2769 [label="mcl_cb.h",height=0.2,width=0.4,color="red",URL="$mcl__cb_8h.html"]; + Node2770 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2770 [label="mcl_node.h",height=0.2,width=0.4,color="black",URL="$mcl__node_8h.html"]; + Node2771 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2771 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2769 -> Node2771 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2772 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2772 [label="mcl_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__timer_8h.html"]; + Node2773 -> Node2772 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2773 [label="mcl_timer_handler.h",height=0.2,width=0.4,color="black",URL="$mcl__timer__handler_8h.html"]; + Node2774 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2774 [label="../common/mcl_periodic_timer.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__timer_8h.html"]; + Node2775 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2775 [label="mcl_periodic_proc.h",height=0.2,width=0.4,color="black",URL="$mcl__periodic__proc_8h.html"]; + Node2776 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2776 [label="mcl_fec.h",height=0.2,width=0.4,color="black",URL="$mcl__fec_8h.html"]; + Node2777 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2777 [label="mcl_stats.h",height=0.2,width=0.4,color="black",URL="$mcl__stats_8h.html"]; + Node2778 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2778 [label="mcl_ses_channel.h",height=0.2,width=0.4,color="black",URL="$mcl__ses__channel_8h.html"]; + Node2766 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2779 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2779 [label="mcl_tx.h",height=0.2,width=0.4,color="red",URL="$mcl__tx_8h.html"]; + Node2781 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2781 [label="mcl_tx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__window_8h.html"]; + Node2782 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2782 [label="mcl_tx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__ctrl_8h.html"]; + Node2783 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2783 [label="mcl_tx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__tx__storage_8h.html"]; + Node2785 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2785 [label="mcl_rx.h",height=0.2,width=0.4,color="black",URL="$mcl__rx_8h.html"]; + Node2786 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2786 [label="mcl_rx_window.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__window_8h.html"]; + Node2787 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2787 [label="mcl_rx_thread.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__thread_8h.html"]; + Node2788 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2788 [label="mcl_rx_ctrl.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__ctrl_8h.html"]; + Node2789 -> Node2769 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2789 [label="mcl_rx_storage.h",height=0.2,width=0.4,color="black",URL="$mcl__rx__storage_8h.html"]; + Node2770 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2771 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2773 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2772 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2774 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2775 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2776 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2777 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2778 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2766 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2779 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2781 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2782 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2783 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2785 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2786 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2787 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2788 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2789 -> Node2728 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__tx__window_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__tx__window_8h__dep__incl.dot new file mode 100644 index 0000000..8f7227f --- /dev/null +++ b/doc/doxygen/norm/html/mcl__tx__window_8h__dep__incl.dot @@ -0,0 +1,15 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node2792 [label="mcl_tx_window.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node2793 -> Node2792 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2793 [label="mcl_cb.h",height=0.2,width=0.4,color="black",URL="$mcl__cb_8h.html"]; + Node2794 -> Node2793 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2794 [label="mcl_includes.h",height=0.2,width=0.4,color="black",URL="$mcl__includes_8h.html"]; + Node2820 -> Node2793 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2820 [label="mcl_fsm.h",height=0.2,width=0.4,color="black",URL="$mcl__fsm_8h.html"]; + Node2793 -> Node2820 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2794 -> Node2820 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node2794 -> Node2792 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; +} diff --git a/doc/doxygen/norm/html/mcl__version_8h__dep__incl.dot b/doc/doxygen/norm/html/mcl__version_8h__dep__incl.dot new file mode 100644 index 0000000..2184520 --- /dev/null +++ b/doc/doxygen/norm/html/mcl__version_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node216 [label="mcl_version.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node217 -> Node216 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node217 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/doxygen/norm/html/rse__fec_8cpp__incl.dot b/doc/doxygen/norm/html/rse__fec_8cpp__incl.dot new file mode 100644 index 0000000..da8edc8 --- /dev/null +++ b/doc/doxygen/norm/html/rse__fec_8cpp__incl.dot @@ -0,0 +1,18 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node243 [label="rse_fec.cpp",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node244 -> Node243 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node244 [label="stdio.h",height=0.2,width=0.4,color="grey75"]; + Node245 -> Node243 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node245 [label="stdlib.h",height=0.2,width=0.4,color="grey75"]; + Node246 -> Node243 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node246 [label="string.h",height=0.2,width=0.4,color="grey75"]; + Node247 -> Node243 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node247 [label="strings.h",height=0.2,width=0.4,color="grey75"]; + Node248 -> Node243 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node248 [label="sys/types.h",height=0.2,width=0.4,color="grey75"]; + Node249 -> Node243 [dir=back,color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node249 [label="../common/mcl_debug.h",height=0.2,width=0.4,color="black",URL="$mcl__debug_8h.html"]; +} diff --git a/doc/doxygen/norm/html/rse__fec_8h__dep__incl.dot b/doc/doxygen/norm/html/rse__fec_8h__dep__incl.dot new file mode 100644 index 0000000..88e508e --- /dev/null +++ b/doc/doxygen/norm/html/rse__fec_8h__dep__incl.dot @@ -0,0 +1,8 @@ +digraph G +{ + edge [fontname="Helvetica",fontsize=10,labelfontname="Helvetica",labelfontsize=10]; + node [fontname="Helvetica",fontsize=10,shape=record]; + Node252 [label="rse_fec.h",height=0.2,width=0.4,color="white", fillcolor="black", style="filled" fontcolor="white"]; + Node253 -> Node252 [color="midnightblue",fontsize=10,style="solid",fontname="Helvetica"]; + Node253 [label="mcl_includes.h",height=0.2,width=0.4,color="red",URL="$mcl__includes_8h.html"]; +} diff --git a/doc/how_to_do_a_release.txt b/doc/how_to_do_a_release.txt new file mode 100644 index 0000000..e3c0d59 --- /dev/null +++ b/doc/how_to_do_a_release.txt @@ -0,0 +1,256 @@ +$Id: how_to_do_a_release.txt,v 1.11 2004/12/08 11:41:19 roca Exp $ + + ------------------- + HOW TO DO A RELEASE + ------------------- + + + +COMMON METHODOLOGY +------------------ + +LDPC part: +---------- + +0- make sure the whole directory is up to date + cd ldpc + cvs update . + If ever there is a conflict or a source file has been updated, the WHOLE + project must be completely validated + +1- check doc/RELEASE_NOTE + check src/ldpc_fec.cpp, LDPCFecSession::MoreAbout() and update the + version number/date + +2- do a cvs commit -m"release xxx" . at the highest level (ldpc dir) + +3- do a cvs tag "release-1-3" . at the highest level (ldpc dir) + +4- clean everything + This must be done both with a linux, freebsd and solaris workstation + cd ldpc + make cleanall + Make sure that the bin directories have been completely cleaned + (several subdir may have been created during tests) + +5- check there is no core file and remove them if any + cd ldpc + find . -name *core* -print -exec rm {} \; + +6- copy the complete distrib to ~/distrib and change directory name to + reflect version number + mkdir ~/distrib + cp -R ldpc ~/distrib + cd ~/distrib + mv ldpc ldpc_v1.3 + +7- remove confidential and unnessary directories and files + cd ../ldpc/ + rm -rf test + rm -rf common + +8- remove all *.ncb and *.suo files specific to Visual.Net in ldpc + directorie. + +9- remove the windows binaries in + cd /bin/win32 + rm * + rm tmp/* + +10- remove the CVS entries + find . -name CVS -print -exec rm -rf {} \; + remove CVS backup file versions when there's a conflict + find . -name ".#*" -print -exec rm {} \; + remove VI temp files: + find . -name *.cpp~ -print -exec rm {} \; + find . -name *.h~ -print -exec rm {} \; + find . -name *.txt~ -print -exec rm {} \; + find . -name Makefile~ -print -exec rm {} \; + find . -name "*.TXT~" -print -exec rm {} \; + +11- genereate doxygen pages and copy LDPCFecSession man page to ldpc/man; + remove generated doxygen pages + cd doc/doxygen + doxygen + cp man/man3/LDPCFecSession.3 ../../man + rm -rf html + rm -rf man + remove all code fragments from the man/LDPCFecSession.3 man page + +12- edit all Makefiles and remove the "dependancy" section... Remove whatever + FOLLOWS the following three lines: + # Dependencies automatically created by makedepend + # + # DO NOT DELETE THIS LINE -- make depend depends on it. + +13- create the source archives + tar cvzf ldpc_v1.3_src.tgz ldpc_v1.3 + and the same for ldpc. Then: + zip -r ldpc_v1.3_src.zip ldpc_v1.3 + + +MCLv3/LDPC part: +---------------- + +0- make sure the whole directory is up to date + cd mclv3 + cvs update . + If ever there is a conflict or a source file has been updated, the WHOLE + project must be completely validated (chec/checkall run and + interoperability tests performed)! + +1- check src/common/mcl_version.h + the version number and date must be ok + +2- check doc/RELEASE_NOTE and add both a column in the table and section + for the new release if not already done + +3- check src/alc/mcl_profile.h + By default there must be: + + * LCT_SCHED1 set + * VIRTUAL_TX_MEM set and VIRTUAL_TX_MAX_PHY_MEM_SIZE set to 100MB + * VIRTUAL_RX_MEM set and VIRTUAL_RX_MAX_PHY_MEM_SIZE set to 100MB + * ANTICIPATED_TX_FOR_PUSH set + * #define ANTICIPATED_TX_FOR_PUSH_AGGRESSIVENESS 4 /* default */ + * RSE_FEC set + * LDPC_FEC set + + There must NOT be: + + * SIMUL_LOSSES must not be set + * LCT_SCHED2 should not be set + * LCT_SCHED3 should not be set + * POSTPONE_FEC_DECODING should not be set + +3'- check src/alc/mcl_rx.cpp + The // #define REMOVE_PHY_LAYER_DUPLICATES must NOT be defined + (specific to INRIA) + +4- build everything under linux, solaris and windows and do the following + tests: + - run checkall on the linux and solaris hosts + - run wincheck on the windows host + - perform a simple FCAST transfer (1) from linux to solaris, + (2) from solaris to linux, (3) from linux to windows, and + finally (4) from windows to linux + - check interoperability with TUT Flute. This will usually + require to use -singlelayer mode (to avoid using different + congestion control protocols) and a small object (to always + use Reed-Solomon). Test both directions. + +5- do a cvs commit -m"release xxx" . at the highest level (mcl dir) + +6- do a cvs tag "release-2-1" . at the highest level (mcl dir) + +7- clean everything + This must be done both with a linux and solaris workstation + cd mcl + make cleanall + Make sure that the bin directories have been completely cleaned + (several subdir may have been created during tests) + Do the same in the ldpc dir. + +8- check there is no core file and remove them if any + cd mcl + find . -name *core* -print -exec rm {} \; + Do the same in the ldpc dir. + +9- copy the complete distrib to ~/distrib and change directory name to + reflect version number + mkdir ~/distrib + cp -R mclv3 ~/distrib + cp -R ldpc ~/distrib + cd ~/distrib + mv mclv3 mcl_v2.99.1 + mv ldpc ldpc_v1.1 + ln -s ldpc_v1.1 ldpc + +10- remove confidential directories and files + cd mcl_v2.99.1 + rm -rf test + rm -rf bench + rm doc/how_to_do_a_release.txt + And for ldpc: + cd ../ldpc/ + rm -rf test + +11- remove all *.ncb and *.suo files specific to Visual .Net in both + the mcl and ldpc directories. + find . -name *.ncb -print -exec rm {} \; + find . -name *.suo -print -exec rm {} \; + Remove all pchdir directories specific to Insure. + cd src/alc; + rm -rf pchdir + +12- remove the windows binaries in + cd check/alc/wincheck/bin + rm * + rm tmp/* + +13- remove the CVS entries + find . -name CVS -print -exec rm -rf {} \; + +14- compile the html version of man pages + cd man + make html + Be carefull not to include .ps.gz versions! Remove them if any. + ** Copy fcast.man.1.html to bin/win32 and rename it to fcast.html ** + +15- check all Makefiles (in particular src/Makefile and fcast/Makefile) and + make sure by default they will compile in optimised mode. It looks like: + CFLAGS = -O -g ${OSFLAGS} + +16- edit all Makefiles and remove the "dependancy" section... Remove whatever + FOLLOWS the following three lines: + # Dependencies automatically created by makedepend + # + # DO NOT DELETE THIS LINE -- make depend depends on it. + +17- create the source archives + tar cvzf mcl_v2.99.1_src.tgz mcl_v2.99.1 + and the same for ldpc. Then: + zip -r mcl_v2.99.1_src.zip mcl_v2.99.1 + + +FOR THE BINARY VERSIONS +----------------------- + +We first modify the source distrib directory prepared above, and then +create copies. + +1- Binaries must be compiled in optimized mode... + edit the src/Makefile and fcast/Makefile in the source distrib done + previously and make sure it uses: + CFLAGS = -O -g ${OSFLAGS} + +2- Now copy the complete source distrib done previously and use directory + names that reflect version number/target OS + cd /tmp + cp -R mcl_v2.1 mcl_v2.1_linux_bin + cp -R mcl_v2.1 mcl_v2.1_solaris_bin + cp -R mcl_v2.1 mcl_v2.1_win32_bin + +3- Compile anything under the various OS + +4- Strip the binaries (ie. remove their symbol tables): + cd bin/linux + strip fcast flute robcast_* + and: + cd bin/solaris + strip fcast flute robcast_client robcast_server + DO NOT strip libmclalc.a ! (required to compile check/alc/test*.c) + +5- Binary versions only include the following directories: + bin/ + check/ (with source code!) + doc/ + man/ + Keep the top level Makefile.common file + (required to compile check/alc/test*.c) + Keep the src/common/mcl_lib_api.h file + (required to compile check/alc/test*.c) + Keep the src/alc/mcl_lib_alc_api.h file + (required to compile check/alc/test*.c) + Other directories must be removed from the source distrib done previously. + diff --git a/doc/how_to_report_bugs.txt b/doc/how_to_report_bugs.txt new file mode 100644 index 0000000..dd8947c --- /dev/null +++ b/doc/how_to_report_bugs.txt @@ -0,0 +1,13 @@ +HOW TO REPORT A BUG +------------------- + +fill-in the following squeletton: + +MCL version: mcl_v2.X.X +severity: critical/performances/... +description: ... +corrections: ... (if identified ;-) +identified by: your email address +date: ... + +and send it to mcl-bugs@inrialpes.fr diff --git a/fcast/Makefile b/fcast/Makefile new file mode 100644 index 0000000..5d63741 --- /dev/null +++ b/fcast/Makefile @@ -0,0 +1,222 @@ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Makefile.common + + +# libraries required +ifeq (${OS},linux) + # Linux version + # add MPATROL support if required + # + BINDIR = ../bin/linux + LDPC_BINDIR = ../../ldpc/bin/linux + LIBRARIES = -lc -lm -lpthread + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},solaris) + # Solaris version: + # Warning: SUN recommends to have -lucb at the end of list, + # in order to priviledge SUN's libs to the BSD compatibility + # lib (libucb). + # CC requires: -mt -lpthread for multithreaded applications + # + BINDIR = ../bin/solaris + LDPC_BINDIR = ../../ldpc/bin/solaris + LIBRARIES = -lc -lm -lsocket -lnsl -lposix4 -mt -lpthread -L/usr/ucblib -lucb + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},freebsd) + # FreeBSD version + # + BINDIR = ../bin/freebsd + LDPC_BINDIR = ../../ldpc/bin/freebsd + LIBRARIES = -lm -pthread + # TBC + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},aix) + # AIX version + BINDIR = ../../bin/aix + LDPC_BINDIR = ../../../ldpc/bin/aix + LIBRARIES = -lm -pthread -lc + # TBC + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},hp-ux) + # HP-UX version + BINDIR = ../../bin/hp-ux + LDPC_BINDIR = ../../../ldpc/bin/hp-ux + LIBRARIES = -lc -lm -pthread + # TBC + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},irix) + # IRIX version + BINDIR = ../../bin/irix + LDPC_BINDIR = ../../../ldpc/bin/irix + LIBRARIES = -lc -lm -pthread + # TBC + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +#CFLAGS = ${OSFLAGS} -D${RM_PROTOCOL} ${LARGEFILE_FLAGS} -g -pg -O +CFLAGS = ${OSFLAGS} -D${RM_PROTOCOL} ${LARGEFILE_FLAGS} -g -O -DDEBUG +#CFLAGS = ${OSFLAGS} -D${RM_PROTOCOL} ${LARGEFILE_FLAGS} -O + +# add purify linker for memory debug (Solaris only). +# Purify 4.0 Solaris 2, Copyright (C) 1992-1996 Pure Software Inc. +# +#CCLINK_PURE = purify $(CC) +#CCLINK_PURE = purify -cache-dir=/tmp $(CC) + +# add quantify linker for profiling (Solaris only). +#CCLINK_QUANTIFY = quantify $(CC) + +# list of source and object files +SRCFILES = checksum.c metadata.c filemanage.c fsend.c frecv.c fcast.c +OFILES = ${SRCFILES:.c=.o} + + +###### choose between the ALC / NORM versions ###### + +# Compile either with ALC or NORM support. +# The RM_PROTOCOL and MCL_LIBRARY variables are target-specific. +# In case of ALC, you may have to add libldpc.a depending on what +# FEC codec is used by MCL +# The tool is either fcast (ALC) or fcastn (NORM). + +alc: RM_PROTOCOL = ALC +# Edit the following two lines as appropriate, according to the FEC +# codec in use: if LDPC is used, then add the libbdpc.a library. +# If only RSE is used and if you don't have the LDPC archive, then +# remove the libbdpc.a library. +alc: MCL_LIBRARY = ${BINDIR}/libmclalc.a +alc: MCL_LIBRARY = ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +alc: TARGET_FCAST = ${BINDIR}/fcast +alc: TARGET_FCAST_STATIC = ${BINDIR}/fcast-static +#alc: all + +norm: RM_PROTOCOL = NORM +norm: MCL_LIBRARY = ${BINDIR}/libmclnorm.a +norm: TARGET_FCAST = ${BINDIR}/fcastn +norm: TARGET_FCAST_STATIC = ${BINDIR}/fcastn-static +#norm: all + +#alc_pure: RM_PROTOCOL = ALC +# Edit the following two lines as appropriate, according to the FEC +# codec in use: if LDPC is used, then add the libbdpc.a library. +#alc_pure: MCL_LIBRARY = ${BINDIR}/libmclalc.a +#alc_pure: MCL_LIBRARY = ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +#alc_pure: TARGET_FCAST = ${BINDIR}/fcast +#alc_pure: pure + +#alc_quantify: RM_PROTOCOL = ALC +# Edit the following two lines as appropriate, according to the FEC +# codec in use: if LDPC is used, then add the libbdpc.a library. +#alc_quantify: MCL_LIBRARY = ${BINDIR}/libmclalc.a +#alc_quantify: MCL_LIBRARY = ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +#alc_quantify: TARGET_FCAST = ${BINDIR}/fcast +#alc_quantify: quantify + +#norm_pure: RM_PROTOCOL = NORM +#norm_pure: MCL_LIBRARY = ${BINDIR}/libmclnorm.a +#norm_pure: TARGET_FCAST = ${BINDIR}/fcastn +#norm_pure: pure + +#norm_quantify: RM_PROTOCOL = NORM +#norm_quantify: MCL_LIBRARY = ${BINDIR}/libmclnorm.a +#norm_quantify: TARGET_FCAST = ${BINDIR}/fcastn +#norm_quantify: quantify + +###### Dependancies ###### + +all: alc norm + +#${TARGET_FCAST}: ${OFILES} ${MCL_LIBRARY} + +alc: ${OFILES} ${MCL_LIBRARY} + @echo "** Compiling fcast-ALC using the MCL library..." + ${CC} ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} -o ${TARGET_FCAST} + ${CC} -static -static-libgcc ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} -o ${TARGET_FCAST_STATIC} + +norm: ${OFILES} ${MCL_LIBRARY} + @echo "** Compiling fcast-ALC using the MCL library..." + ${CC} ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} -o ${TARGET_FCAST} + ${CC} -static -static-libgcc ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} -o ${TARGET_FCAST_STATIC} + +#pure: ${OFILES} ${MCL_LIBRARY} +# @echo "** Compiling fcast using the MCL library..." +# ${CCLINK_PURE} ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} -o ${TARGET_FCAST} + +#quantify: ${OFILES} ${MCL_LIBRARY} +# @echo "** Compiling fcast using the MCL library..." +# ${CCLINK_QUANTIFY} ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} -o ${TARGET_FCAST} + +clean : + @for f in core ${OFILES} *_pure* *.pure_* .pur* *purify* ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall_alc : clean + @for f in ${BINDIR}/fcast; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + + +cleanall_norm : clean + @for f in ${BINDIR}/fcastn; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + + +cleanall : clean + @for f in ${BINDIR}/fcast ${BINDIR}/fcastn; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +checksum.o: checksum.h +metadata.o: fcast.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +metadata.o: checksum.h metadata.h macros.h filemanage.h fsend.h frecv.h +filemanage.o: fcast.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +filemanage.o: checksum.h metadata.h macros.h filemanage.h fsend.h frecv.h +fsend.o: fcast.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +fsend.o: checksum.h metadata.h macros.h filemanage.h fsend.h frecv.h +frecv.o: fcast.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +frecv.o: checksum.h metadata.h macros.h filemanage.h fsend.h frecv.h +fcast.o: fcast.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +fcast.o: checksum.h metadata.h macros.h filemanage.h fsend.h frecv.h diff --git a/fcast/README b/fcast/README new file mode 100644 index 0000000..59273b8 --- /dev/null +++ b/fcast/README @@ -0,0 +1,54 @@ + $Id: README,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ + + ----------------------------------------------------------- + FCAST: Multicast File Transfert Application over MCL Lib + (as defined in the ALC internet draft) + + README - Vincent Roca, Julien LABOURE + ----------------------------------------------------------- + + +1- USING THE FCAST TOOLS +------------------- + + ./fcast -help + for a list of commands/parameters available. + + Sample: + as Sender: ./fcast -send -a230.1.2.3/1234 send.me + Sends the file send.me to 230.1.2.3/1234 multicast group. + + as Seceiver: ./fcast -recv -a230.1.2.3/1234 + Get and save to current directory file(s) + (and folders if recursive mode is ON) from + 230.1.2.3/1234 multicast group. + +NOTES +---- + + Note about recursive mode for directories transferts : + This mode allows to send recusrively a directory with all files + and subdirs. + The arborescence is created in the receiver current directory. + ie: + 1/ if we use -r "../foo/" as sender parameter, then fcast will + send all files and subdirs in "../foo/" from current dir + On receiver side, a "foo/" directory will be created in current + dir and filled with the corresponding files. + + 2/ if we use -r "/home/user/foo/" as sender parameter, then + on receiver side, a "home/user/foo/ directory will be created + in current dir and filled with the corresponding files. + + THIS MODE IS CURRENTLY NOT FULLY IMPLEMENTED, so you *may* + notice some bugs, or hasardous results if tool is used in + non-standard ways... + ie: ./fcast -send -r ~/../$HOME/././foo/ *MAY* not work :-) + + Also, files modes/permissions are not supported at the moment. + + + --------------------------- + For further informations/comments, or if you find this tool + interesting, then send an email at: Vincent.Roca@inrialpes.fr + Julien.Laboure@inrialpes.fr diff --git a/fcast/checksum.c b/fcast/checksum.c new file mode 100644 index 0000000..985f7a8 --- /dev/null +++ b/fcast/checksum.c @@ -0,0 +1,127 @@ +/* $Id: checksum.c,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * checksum.c + * + * Checksum computing implementation. + */ + +#include "checksum.h" +#include + + +unsigned short ComputeSum_obsolete( unsigned short *Buffer, int count, char *odd_boundary, int *nb_odd ) +{ + register long sum = 0; + unsigned short not_checksum = 0; + unsigned short oddbyte = 0; + char is_odd = (char)(count%2); + if(is_odd && nb_odd != NULL) (*nb_odd) = (*nb_odd)+1; + + while( count > 1 ) /* This is the inner loop */ + { + sum += *Buffer++; + count -= 2; + } + if( count > 0 ) /* Add left-over byte, if any */ + { + *((unsigned char *) &oddbyte) = *(unsigned char*)Buffer; + sum += oddbyte; + + } + + /* Fold 32bits sum to 16 bits */ + while ( sum >> 16 ) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + + if( odd_boundary && *odd_boundary ) + { + sum = ((sum & 0xFF00)>>8) + ((sum & 0x00FF)<<8); + } + + if( odd_boundary ) + *odd_boundary = is_odd; + + not_checksum = (unsigned short)sum; +/* PRINT(("<-ComputeSum: Sum=0x%lX)\n", not_checksum)) */ + return not_checksum; +} + + + +unsigned short ComputeSum( unsigned short *Buffer, int count, unsigned char *swap ) +{ + unsigned register long sum = 0; + unsigned short not_checksum = 0; + unsigned short oddbyte = 0; + unsigned char inverse_swap = 0; + + while( count > 1 ) /* This is the inner loop */ + { + sum += *Buffer++; + count -= 2; + if ( sum >> 16 ) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + } + if( count > 0 ) /* Add left-over byte, if any */ + { + *((unsigned char *) &oddbyte) = *(unsigned char*)Buffer; + sum += oddbyte; + inverse_swap = 1; + } + + /* Fold 32bits sum to 16 bits */ + while ( sum >> 16 ) + { + sum = (sum & 0xFFFF) + (sum >> 16); + } + + if(swap && *swap) + { + sum = ((sum & 0xFF00)>>8) + ((sum & 0x00FF)<<8); + } + + if(swap && inverse_swap) + (*swap) = ((*swap)+1)%2; + + not_checksum = (unsigned short)sum; + return not_checksum; +} + + +unsigned short ComputeChecksum( int sum, int swap) +{ + unsigned short checksum; + + if((swap)) + { + sum = ((sum & 0xFF00)>>8) + ((sum & 0x00FF)<<8); + } + + checksum = ~sum; + return checksum; +} diff --git a/fcast/checksum.h b/fcast/checksum.h new file mode 100644 index 0000000..b97052e --- /dev/null +++ b/fcast/checksum.h @@ -0,0 +1,30 @@ +/* $Id: checksum.h,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * checksum.h + * + * Checksum computing headers. + */ + +unsigned short ComputeSum( unsigned short *Buffer, int count, unsigned char *swap ); +unsigned short ComputeChecksum( int sum, int swap); diff --git a/fcast/fcast.c b/fcast/fcast.c new file mode 100644 index 0000000..15f809f --- /dev/null +++ b/fcast/fcast.c @@ -0,0 +1,1083 @@ +/* $Id: fcast.c,v 1.32 2005/05/23 15:05:33 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * fcast.c + * + * Fcast file transfert tool over MCL Multicast Library. + */ +#include "fcast.h" + +static void Usage (int argc, char *argv[]); +static void ParseCommandLine(int argc, char *argv[]); +static void interrupted (void); +static int extract_addr (char *addr_string, struct sockaddr **addr, + int port); + + + +/******** Globals */ + +/* + * global variables common to ALC / NORM + */ +int id = 0; +int verbose = 0; +int stats = 0; +struct sockaddr *addr = NULL; /* session address (IPv4 or IPv6) */ +struct sockaddr *src_addr = NULL; /* sender address (IPv4 or IPv6) */ +struct sockaddr *mcast_if_addr = NULL; /* interface address (IPv4 or IPv6) */ +char *mcast_if_name = NULL; /* interface name (IPv4 or IPv6) */ +int port = 9998; +int demux_label = 0; +int ttl = 1; +float fec_ratio = 1.5; + +int mode = 0; +int reuse_tx_buff = 1; + +int overwrite = PROMPT; +char fileparam[MAX_PATH+MAX_FILENAME]; +bool recursive = false; +bool meta_object_mode = false; +#ifdef WIN32 +int pause = 0; +int ip_version = 4; +#endif +int silent = 0; +int tx_huge_file = 0; +#define MAX_FILE_NAME_LEN 256 +char tmp_dir[MAX_FILE_NAME_LEN]; +int tmp_dir_set = 0; +int txprof_set = 0; /* set tx profile only once */ +int txprof_mode = MCL_TX_PROFILE_MID_RATE_INTERNET; +int txprof_dt_size = 0; /* default datagram size in bytes */ +double txprof_rate = 0.0; /* default rate in pkts/s (converted + from bps)*/ +#if defined(ALC) +int congestion_control = FLID_SL_CC; +#else +int congestion_control = 0; +#endif + +#if defined(ALC) +/* + * global variables specific to ALC + */ +int nb_layers = 0; +int nb_tx = 1; +int delivery_mode = DEL_MODE_PUSH; +int optimode = OPTIMIZE_SPEED; + + +#elif defined(NORM) +/* + * global variables specific to NORM + */ +#endif /* RM_PROTOCOL */ + + +int +main (int argc, char *argv[]) +{ + int err = 0; /* return value of mcl_ctl functions */ + + signal(SIGINT, (sighandler_t)interrupted); + +#ifdef WIN32 + /* Quick and dirty hack to access WSA functions */ + if (id == 0) { + if ((id = mcl_open("r")) < 0) + EXIT(("Fcast: ERROR, mcl_open failed\n")) + } +#endif + + ParseCommandLine(argc, argv); /* Parameters parsing... */ + + if (mode == SEND) { /* sender */ + if ((id = mcl_open("w")) < 0) + EXIT(("FcastSend: ERROR, mcl_open(w) failed\n")) + } + else if (mode == RECV) { /* or receiver */ + if ((id = mcl_open("r")) < 0) + EXIT(("FcastRecv: ERROR, mcl_open(r) failed\n")) + } else { /* or what? */ + PRINT(("Error: -send or -recv mode required\n")) + Usage(argc, argv); + return -1; + } + + /* specify few important parameters... */ + err += mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose, sizeof(verbose)); + EXIT_ON_ERROR(err, ("Fcast: ERROR, mcl_ctl failed for VERBOSITY\n")) + err += mcl_ctl(id, MCL_OPT_STATS, (void*)&stats, sizeof(int)); + EXIT_ON_ERROR(err, ("Fcast: ERROR, mcl_ctl failed for STATS\n")) +#if defined(ALC) + if (congestion_control > 0) { /* must be before TX_PROFILE */ + err += mcl_ctl(id, MCL_OPT_SET_CC_SCHEME, (void*)&congestion_control, + sizeof(congestion_control)); + EXIT_ON_ERROR(err, ( + "Flute: ERROR, mcl_ctl failed for MCL_OPT_SET_CC_SCHEME\n")) + } +#endif /* RM_PROTOCOL */ + if (txprof_dt_size == 0) { + err += mcl_ctl(id, MCL_OPT_TX_PROFILE, (void*)&txprof_mode, + sizeof(txprof_mode)); + EXIT_ON_ERROR(err, ( + "Fcast: ERROR, mcl_ctl failed for TX_PROFILE\n")) + } + if (txprof_dt_size > 0) { /* must be after TX_PROFILE */ + err += mcl_ctl(id, MCL_OPT_DATAGRAM_SIZE, + (void*)&txprof_dt_size, sizeof(txprof_dt_size)); + EXIT_ON_ERROR(err, ( + "Fcast: ERROR, mcl_ctl failed for DATAGRAM_SIZE %d\n", + txprof_dt_size)) + } + if (txprof_rate > 0.0) { /* must be after TX_PROFILE */ + err += mcl_ctl(id, MCL_OPT_TX_RATE, + (void*)&txprof_rate, sizeof(txprof_rate)); + EXIT_ON_ERROR(err, ( + "Fcast: ERROR, mcl_ctl failed for TX_RATE %d\n", + txprof_rate)) + } + +#if defined(ALC) + if (nb_layers > 0) { + err += mcl_ctl(id, MCL_OPT_LAYER_NB, (void*)&nb_layers, sizeof(int)); + EXIT_ON_ERROR(err, ("Fcast: ERROR, mcl_ctl failed for LAYER_NB\n")) + } +#endif /* RM_PROTOCOL */ + if (addr != NULL) { + int addr_len; + addr_len = (addr->sa_family == AF_INET6) ? + sizeof(struct sockaddr_in6) : + sizeof(struct sockaddr_in); + err += mcl_ctl(id, MCL_OPT_BIND, (void*)addr, addr_len); + EXIT_ON_ERROR(err, ("Fcast: ERROR, mcl_ctl failed for BIND\n")) + } + if (mcast_if_addr != NULL) { /* in host format! */ + err += mcl_ctl(id, MCL_OPT_SET_NETIF_ADDR, + (void*)mcast_if_addr, sizeof(*mcast_if_addr)); + EXIT_ON_ERROR(err, ("Fcast: ERROR, mcl_ctl failed for SET_NETIF_ADDR\n")) + } +#ifndef WIN32 + else if (mcast_if_name != NULL) { + err += mcl_ctl(id, MCL_OPT_SET_NETIF_NAME, + (void*)mcast_if_name, strlen(mcast_if_name)); + EXIT_ON_ERROR(err, ("Fcast: ERROR, mcl_ctl failed for SET_NETIF_NAME\n")) + } +#endif /* OS */ +#if defined(ALC) + if (demux_label > 0) { + err += mcl_ctl(id, MCL_OPT_DEMUX_LABEL, (void*)&demux_label, + sizeof(demux_label)); + EXIT_ON_ERROR(err, ( + "Fcast: ERROR, mcl_ctl failed for DEMUX_LABEL\n")) + } +#endif /* RM_PROTOCOL */ + if (ttl >= 0) { + err += mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + EXIT_ON_ERROR(err, ( + "Fcast: ERROR, mcl_ctl failed for TTL\n")) + } +#if defined(ALC) + if (nb_tx > 1) { + err += mcl_ctl(id, MCL_OPT_NB_OF_TX, (void*)&nb_tx, + sizeof(nb_tx)); + EXIT_ON_ERROR(err, ( + "Fcast: ERROR, mcl_ctl failed for NB_OF_TX\n")) + } +#endif /* RM_PROTOCOL */ + if (tmp_dir_set) { + err += mcl_ctl(id, MCL_OPT_TMP_DIR, (void*)&tmp_dir, + strlen(tmp_dir)); + EXIT_ON_ERROR(err, ( + "Fcast: ERROR, mcl_ctl failed for TMP_DIR \"%s\"\n", + tmp_dir)) + } +#if defined(ALC) + err += mcl_ctl(id, MCL_OPT_DELIVERY_MODE, (void*)&delivery_mode, + sizeof(delivery_mode)); + EXIT_ON_ERROR(err, ("Fcast: ERROR, mcl_ctl failed for DELIVERY_MODE\n")) + if (meta_object_mode) { + err += mcl_ctl(id, MCL_OPT_SET_META_OBJECT_ONLY_MODE, NULL, 0); + EXIT_ON_ERROR(err, ("Fcast: ERROR, mcl_ctl failed for META_OBJECT_ONLY_MODE\n")) + } + +#endif /* RM_PROTOCOL */ + + if (mode == SEND) /*sender */ + FcastSend(); + else if (mode == RECV) /* or receiver */ + FcastRecv(); + +#ifdef WIN32 + if (pause) { + system("pause"); + } + WSACleanup(); +#endif + return 0; +} + + + +void Usage (int argc, char *argv[]) +{ + int err = 0; /* return value of mcl_ctl functions */ + + if (id == 0) { /* need an MCL endpoint first */ + if ((id = mcl_open("r")) < 0) + EXIT(("Fcast: Usage: ERROR, mcl_open failed\n")) + } + + PRINT(("\nFCAST Multicast File Transfert Tool\n")) + + mcl_ctl(id, MCL_OPT_MOREABOUT, NULL, 0); + EXIT_ON_ERROR(err, ("Fcast: Usage: mcl_ctl failed for MOREABOUT\n")) + + PRINT(("\n\n")) + PRINT(("USAGE (sender) %s -send [options] file\n", argv[0])) + PRINT((" or %s -send [options] -R directory\n", argv[0])) + PRINT((" (receiver) %s -recv [options]\n\n", argv[0])) + PRINT(("COMMON OPTIONS\n")) + PRINT((" -help this help\n")) + PRINT((" -send or -recv choose Fcast mode: sender or receiver.\n")) + PRINT((" -an[/p] set the uni/multicast IPv4/IPv6 address or hostname to n\n")) + PRINT((" and port number to p (default 127.0.0.1/%d)\n", port)) +#ifdef WIN32 + PRINT((" -ipvn IP version: 4 or 6 (default: 4)\n")) +#endif + PRINT((" -ifan (InterFace Address) the network interface to use is the\n")) + PRINT((" one attached to the local IPv4/IPv6 addr or host name n\n")) + PRINT((" Only used on multi-homed hosts/routers.\n")) +#ifndef WIN32 + PRINT((" -ifnstr (InterFace Name) the network interface to use is the\n")) + PRINT((" one attached to the interface name str (e.g. -ifneth0)\n")) + PRINT((" Only used on multi-homed hosts/routers.\n")) +#endif /* OS */ +#if defined(ALC) + PRINT((" -demuxn set the LCT Transport Session Id (TSI) to n (default 0)\n")) + PRINT((" - at a sender TSI is included in each packet sent\n")) + PRINT((" - at a receiver {src_addr; TSI} is used for packet filtering\n")) +#elif defined(NORM) + /* no equivalent */ +#endif /* RM_PROTOCOL */ + PRINT((" -vn set MCL verbosity level to n (add statistics too)\n")) + PRINT((" -statn set MCL statistic level to n (0: none, 1: final, 2: all)\n")) + PRINT((" -silent silent mode\n")) + PRINT((" -tmpdir set temporary directory to dir (e.g. -tmp/home/toto/tmp/)\n")) + PRINT((" (unix default: \"/tmp\")\n")) +#if defined(ALC) + PRINT((" -objaggr set object aggregation mode (AKA meta_object). Highly\n")) + PRINT((" efficient when sending a large number of small objects.\n")) + PRINT((" Requires the recursive tx mode at a sender.\n")) + PRINT((" -ospeed use it to optimize speed (default)\n")) + PRINT((" -ospace use it to reduce the required memory at receivers\n")) + PRINT((" -ocpu use it if receiver is CPU limited\n")) +#elif defined(NORM) + /* no equivalent */ +#endif /* RM_PROTOCOL */ +#ifdef WIN32 + PRINT((" -P Request user input (pause) before exiting (for win console)\n")) +#endif + PRINT(("TRANSMISSION PROFILES\n")) + PRINT((" one can use either predefined profiles, or do everything by hand\n")) + PRINT((" or redefine some parameters of the predefined profiles\n")) + PRINT((" -plow | -pmed | -phigh predefined tx profiles for Low|Medium|High\n")) + PRINT((" Speed Internet. (default: medium)\n")) + PRINT((" specifies: number of layers, rate on base layer, datagram\n")) + PRINT((" size, and either FLID-SL (default) or RLC cong. control\n")) + PRINT((" -plan predefined tx profile for High Speed LAN\n")) + PRINT((" specifies: 1 layer, rate, datagram size, and no cong.\n")) + PRINT((" control\n")) + PRINT((" -psize[/rate] sets one (or two) parameters:\n")) +#if defined(ALC) + PRINT((" size is the datagram size (bytes) (used by sender/recv)\n")) + PRINT((" rate is the base layer tx rate (bits/s) (used by sender)\n")) + PRINT((" -ln set number of layers to n\n")) + PRINT((" -ccn set congestion control (CC) scheme to n:\n")) + PRINT((" 0 for no CC (automatically selects 1 transmission layer)\n")) + PRINT((" 1 for RLC (often needed for interoperability tests)\n")) + PRINT((" 2 for FLID_SL (default, less aggressive than RLC)\n")) + PRINT((" Must be specified on both sender and receivers sides!\n")) +#endif + PRINT(("SENDER SPECIFIC OPTIONS\n")) + PRINT((" -ttln set the TTL (Time To Live) to n (default 1)\n")) + PRINT((" -R recursive transmission of a whole directory content\n")) +#if defined(ALC) + PRINT((" -cont continuous delivery mode (same as -repeat)\n")) + PRINT((" also known as ``on-demand'' mode (default is ``push'')\n")) + PRINT((" -repeatn repeat n times on each layer then stop\n")) + PRINT((" ignored in ``on-demand mode''\n")) +#elif defined(NORM) + /* no equivalent */ +#endif /* RM_PROTOCOL */ + PRINT((" -fecn set FEC expansion ratio to n, floating point value >= 1.0.\n")) + PRINT((" (default is %.2f). A ratio of 1.0 means no FEC as it is\n", fec_ratio)) + PRINT((" the n/k ratio, inverse of the so-called \"code rate\".\n")) + PRINT(("RECEIVER SPECIFIC OPTIONS\n")) + PRINT((" -srcn set the source IPv4/IPv6 addr or hostname to n\n")) + PRINT((" {src_addr; TSI} is used for incoming packet filtering.\n")) + PRINT((" -int|-never|-force set the overwriting mode:\n")) + PRINT((" interactive: user is prompted if file already exists\n")) + PRINT((" never: never overwrite an existing file\n")) + PRINT((" force: always write file, even if it already exists\n")) + PRINT(("Type \"CTRL-C\" to abort\n")) +#ifdef WIN32 + system("pause"); +#endif + exit(0); +} + + + +#if defined(ALC) +/* + * ALC version + */ +static void +ParseCommandLine (int argc, char *argv[]) +{ + int c; + char *OptList = "a:v:h:l:s:r:o:p:f:n:i:c:RPt:d:"; + bool address_set = false; + char addr_str[256]; /* remote name string */ + +#ifdef SOLARIS + extern char *optarg; +#elif defined(WIN32) + char *optarg = NULL; +#endif + + if(argc < 2) + Usage(argc, argv); + + +#ifdef WIN32 + while ((c = GetOption(argc, argv, OptList, &optarg)) != 0) +#else + while ((c = getopt(argc, argv, OptList)) != EOF) +#endif + { + switch (c) { + case 'a': + /* process addr/port argument */ + char *p; + + if (*optarg == '\0') { + EXIT(( "Fcast: ERROR, bad argument -a%s: do not use extra space\n", + optarg)) + } + strncpy(addr_str, optarg, sizeof(addr_str)); + addr_str[255] = '\0'; + if ((p = strchr(addr_str, '/')) != NULL) { + *p = '\0'; + /* in host order */ + port = (unsigned short)atoi(p+1); + } + address_set = true; + break; + case 'd': + if (!strncmp(optarg, "emux", 4) && isdigit((int)*(optarg+4))) { + demux_label = atoi(optarg+4); + } + else + EXIT(("Fcast: ERROR, bad argument -d%s (NB: dont use space between -demux and value)\n", optarg)) + break; + case 'v': /* verbosity level */ + if (isdigit((int)*optarg)) { + verbose = atoi(optarg); + if (verbose > 0) + stats = 2; + } else + EXIT(("Fcast: ERROR, bad argument -v%s\n", optarg)) + break; + case 'h': + Usage(argc, argv); + break; + case 'l': /* number of layers */ + if (isdigit((int)*optarg)) { + nb_layers = atoi(optarg); + } else + EXIT(("Fcast: ERROR, bad argument -l%s\n", optarg)) + break; + case 't': /* ttl value */ + if (!strncmp(optarg, "tl", 2) && + isdigit((int)*(optarg+2))) { + ttl = atoi(optarg+2); + } else if(!strncmp(optarg, "mp", 2)) { + strncpy(tmp_dir, optarg+2, sizeof(tmp_dir)); + tmp_dir[MAX_FILE_NAME_LEN-1] = 0; + /* add final / and \0 if not already present */ + if (tmp_dir[strlen(tmp_dir)-1] != '/' && + strlen(tmp_dir) <= MAX_FILE_NAME_LEN-2) + strcat(tmp_dir, "/"); + tmp_dir_set = 1; + } + else + EXIT(("Fcast: ERROR, bad argument -t%s\n", optarg)) + break; + case 's': + if (!strcmp(optarg, "end")) + mode = SEND; + else if (!strncmp(optarg, "rc", 2)) { + /* process addr argument */ + + if (*(optarg + 2) == '\0') { + EXIT(("Fcast: ERROR, bad argument -s%s: do not use extra space\n", optarg)) + } + strncpy(addr_str, optarg + 2, sizeof(addr_str)); + addr_str[255] = '\0'; + if (extract_addr(addr_str, &src_addr, 0) < 0) { + EXIT(("Fcast: ERROR, extract_addr failed for src_addr argument -s%s\n", optarg)) + } + } else if(!strcmp(optarg, "ilent")) + silent = 1; + else if(!strncmp(optarg, "tat", 3)) { + if (isdigit((int)*(optarg+3))) + stats = atoi(optarg+3); + else + EXIT(("Fcast: ERROR, bad argument -s%s\n (NB: dont use space between -stat and value)", optarg)) + } else + EXIT(("Fcast: ERROR, bad argument -s%s\n", optarg)) + break; + case 'r': + if (!strcmp(optarg, "ecv")) + mode = RECV; + else if(!strncmp(optarg, "epeat", 5) && + isdigit((int)*(optarg+5))) { + /* nb of tx is original_tx + repeat_nb*/ + nb_tx = atoi(optarg+5) + 1; + } else + EXIT(("Fcast: ERROR, bad argument -r%s (NB: dont use space between -repeat and value)\n", optarg)) + break; + case 'o': + if (!strcmp(optarg, "space")) { + optimode = OPTIMIZE_SPACE; + } else if(!strcmp(optarg, "speed")) { + optimode = OPTIMIZE_SPEED; + } else if(!strcmp(optarg, "cpu")) { + optimode = OPTIMIZE_CPU; + } else if(!strcmp(optarg, "bjaggr")) { + meta_object_mode = true; + } else { + EXIT(("Fcast: ERROR, bad argument -o%s\n", + optarg)) + } + break; + case 'p': + if (txprof_set) { + EXIT(("Fcast: ERROR, tx profile can be set only once\n")) + } else { + txprof_set = 1; + } + if (!strcmp(optarg, "low")) { + txprof_mode = MCL_TX_PROFILE_LOW_RATE_INTERNET; + } else if(!strcmp(optarg, "med")) { + txprof_mode = MCL_TX_PROFILE_MID_RATE_INTERNET; + } else if(!strcmp(optarg, "high")) { + txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_INTERNET; + } else if(!strcmp(optarg, "lan")) { + txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_LAN; + congestion_control = NO_CC; /* true in a LAN! */ + } else if (*optarg) { + /* process size/rate argument */ + char str[128]; /* size/rate string */ + char *p; + int rate = 0; + + strncpy(str, optarg, sizeof(str)); + str[127] = '\0'; + if ((p = strchr(str, '/')) != NULL) { + *p = '\0'; /* cut str into two strings*/ + rate = (int)atoi(p+1); + if (rate <= 0) { + EXIT(("Fcast: ERROR, invalid rate for argument -p%s\n", optarg)) + } + } + txprof_dt_size = (int)atoi(str); + if (txprof_dt_size <= 0) { + EXIT(("Fcast: ERROR, invalid size for argument -p%s\n", optarg)) + } + if (rate > 0) { + txprof_rate = (double)rate / + ((double)txprof_dt_size * 8.0); + /* no less than 1 pkt/s */ + txprof_rate = max(1.0, txprof_rate); + } + /*PRINT(("fcast: txprof_dt_size=%d, rate=%d, txprof_rate=%f\n", txprof_dt_size, rate, txprof_rate))*/ + } else { + EXIT(("Fcast: ERROR, bad argument -p%s\n", optarg)) + } + break; + + case 'R': +#ifdef SOLARIS + EXIT(("Flute: ERROR, argument -R not supported with this release on Solaris.\n")) +#endif + recursive = 1; + break; + + case 'P': +#ifdef WIN32 + pause = 1; +#endif + break; + + case 'f': + if (!strncmp(optarg, "ec", 2)) { + if (isdigit((int)*(optarg+2))) + fec_ratio = (float)atof(optarg+2); + else + EXIT(("Fcast: ERROR, bad argument -f%s (NB: dont use space between -fec and value)\n", optarg)) + } else if (!strcmp(optarg, "orce")) { + overwrite = ALWAYS; + } else + EXIT(("Fcast: ERROR, bad argument -f%s\n", optarg)) + break; + case 'c': + + if (!strcmp(optarg, "ont")) { + delivery_mode = DEL_MODE_ON_DEMAND; + } else if (!strncmp(optarg, "c", 1)) { + int temp = (int)atoi(optarg+1); + switch(temp){ + case 0: + congestion_control = NO_CC; + if (nb_layers == 0) nb_layers = 1; + break; + case 1: + congestion_control = RLC_CC; + break; + case 2: + congestion_control = FLID_SL_CC; + break; + } + } else + EXIT(("Fcast: ERROR, bad argument -c%s\n", optarg)) + break; + case 'i': + if (!strcmp(optarg, "nt")) { + overwrite = PROMPT; + } +#ifndef WIN32 + else if (!strncmp(optarg, "fn", 2)) { + /* this is an interface name */ + char name_str[256]; /* if name string */ + + if (*(optarg + 2) == '\0') { + EXIT(("Fcast: ERROR, bad argument -i%s: do not use extra space\n", optarg)) + } + //strncpy(name_str, optarg + 2, sizeof(name_str)); + strncpy(name_str, optarg + 2, 256); + name_str[255] = '\0'; + mcast_if_name = (char *) + calloc(1, strlen(name_str) + 1); + if (mcast_if_name == NULL) { + EXIT(("Fcast: ERROR, calloc failed during -i%s argument processing\n", optarg)) + } + strncpy(mcast_if_name, name_str, strlen(name_str)); + } +#else + else if (!strncmp(optarg, "pv", 2)) { + ip_version = (int)atoi(optarg+2); + if (ip_version != 4 && ip_version !=6) + { + EXIT(("Fcast: ERROR, unknown IP version %i. Specify IP version 4 or 6\n",ip_version)) + } + } +#endif /* OS */ + else if (!strncmp(optarg, "fa", 2)) { + /* process addr/hostname argument */ + char addr_str[256]; /* addr/name string */ + + if (*(optarg + 2) == '\0') { + EXIT(("Fcast: ERROR, bad argument -i%s: do not use extra space\n", optarg)) + } + strncpy(addr_str, optarg + 2, sizeof(addr_str)); + addr_str[255] = '\0'; + if (extract_addr(addr_str, &mcast_if_addr, 0) < 0) { + EXIT(("Fcast: ERROR, address extraction failed during -i%s argument processing\n", optarg)) + } + } else + EXIT(("Fcast: ERROR, bad argument -i%s\n", optarg)) + break; + case 'n': + if (!strcmp(optarg, "ever")) { + overwrite = NEVER; + } else + EXIT(("Fcast: ERROR, bad argument -n%s\n", optarg)) + break; +#ifdef WIN32 + case 1: + break; +#endif + default: + /* + * NB: getopt returns '?' when finding an + * unknown argument; avoid the following + * error msg in that case + */ + if (c != '?') + PRINT(("bad argument %c\n", c)) + Usage(argc, argv); + break; + } + } + + /* last arg is file name */ + ASSERT((argv[argc-1])) + if (mode == SEND) { + strncpy(fileparam, argv[argc-1], MAX_PATH+MAX_FILENAME); + } + + /* Process address string */ + if (address_set == true && extract_addr(addr_str, &addr, port) < 0) { + EXIT(("Fcast: ERROR, extract_addr failed for session addr argument -a%s\n", addr_str)) + } + + /* Some checks */ + if ((meta_object_mode == true) && (recursive == false) && (mode == SEND)) { + EXIT(("Fcast: ERROR, the \"object aggregation\" mode is only possible in recursive directory transmission mode.\n")) + } +#ifndef WIN32 + if (addr != NULL && addr->sa_family == AF_INET6 && mcast_if_name == NULL) + { + EXIT(("Flute: ERROR, you must specify an interface name (using -ifnstr) with IPv6\n")) + } +#endif +} + +#elif defined(NORM) + +/* + * NORM version + */ +static void +ParseCommandLine (int argc, char *argv[]) +{ + int c; + char *OptList = "a:v:h:s:r:p:f:n:i:RPt:"; + +#ifdef SOLARIS + extern char *optarg; +#elif defined(WIN32) + char *optarg = NULL; +#endif + + if(argc < 2) + Usage(argc, argv); + + +#ifdef WIN32 + while ((c = GetOption(argc, argv, OptList, &optarg)) != 0) +#else + while ((c = getopt(argc, argv, OptList)) != EOF) +#endif + { + switch (c) { + case 'a': + if (*optarg == '\0') { + EXIT(( "Fcast: ERROR, bad argument -a%s\n", optarg)) + } + /* process addr/port argument */ + char addr_str[256]; /* remote name string */ + char *p; + + strncpy(addr_str, optarg, sizeof(addr_str)); + addr_str[255] = '\0'; + if ((p = strchr(addr_str, '/')) != NULL) { + *p = '\0'; + /* in host order */ + port = (unsigned short)atoi(p+1); + } + /* get IPv4/IPv6 addr from argument */ + if (extract_addr(addr_str, &addr, port) < 0) { + EXIT(("Fcast: ERROR, extract_addr failed for session addr argument -a%s\n", optarg)) + } + break; + + case 'v': /* verbosity level */ + if (isdigit((int)*optarg)) { + verbose = atoi(optarg); + if (verbose > 0) + stats = 2; + } else + EXIT(("Fcast: ERROR, bad argument -v%s\n", optarg)) + break; + case 'h': + Usage(argc, argv); + break; + case 't': /* ttl value */ + if (!strncmp(optarg, "tl", 2) && + isdigit((int)*(optarg+2))) { + ttl = atoi(optarg+2); + } else if(!strncmp(optarg, "mp", 2)) { + strncpy(tmp_dir, optarg+2, sizeof(tmp_dir)); + tmp_dir[MAX_FILE_NAME_LEN-1] = 0; + /* add final / and \0 if not already present */ + if (tmp_dir[strlen(tmp_dir)-1] != '/' && + strlen(tmp_dir) <= MAX_FILE_NAME_LEN-2) + strcat(tmp_dir, "/"); + tmp_dir_set = 1; + } + else + EXIT(("Fcast: ERROR, bad argument -t%s\n", optarg)) + break; + case 's': + if (!strcmp(optarg, "end")) + mode = SEND; + else if (!strncmp(optarg, "rc", 2)) { + /* process addr argument */ + char addr_str[256]; /* remote name string */ + + strncpy(addr_str, optarg + 2, sizeof(addr_str)); + addr_str[255] = '\0'; + /* get IPv4/IPv6 addr from argument */ + if (extract_addr(addr_str, &addr, port) < 0) { + EXIT(("Fcast: ERROR, extract_addr failed for src_addr argument -s%s\n", optarg)) + } + } else if(!strcmp(optarg, "ilent")) + silent = 1; + else if(!strncmp(optarg, "tat", 3)) { + if (isdigit((int)*(optarg+3))) + stats = atoi(optarg+3); + else + EXIT(("Fcast: ERROR, bad argument -s%s\n (NB: dont use space between -stat and value)", optarg)) + } else + EXIT(("Fcast: ERROR, bad argument -s%s\n", optarg)) + break; + case 'r': + if (!strcmp(optarg, "ecv")) + mode = RECV; + else + EXIT(("Fcast: ERROR, bad argument -r%s (NB: dont use space between -repeat and value)\n", optarg)) + break; + case 'p': + if (!strcmp(optarg, "low")) { + txprof_mode = MCL_TX_PROFILE_LOW_RATE_INTERNET; + } else if(!strcmp(optarg, "med")) { + txprof_mode = MCL_TX_PROFILE_MID_RATE_INTERNET; + } else if(!strcmp(optarg, "high")) { + txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_INTERNET; + } else if(!strcmp(optarg, "lan")) { + txprof_mode = MCL_TX_PROFILE_HIGH_SPEED_LAN; + } else if (*optarg) { + /* process size/rate argument */ + char str[128]; /* size/rate string */ + char *p; + int rate = 0; + + strncpy(str, optarg, sizeof(str)); + str[127] = '\0'; + if ((p = strchr(str, '/')) != NULL) { + *p = '\0'; /* cut str into two strings*/ + rate = (int)atoi(p+1); + if (rate <= 0) { + EXIT(("Fcast: ERROR, invalid rate for argument -p%s\n", optarg)) + } + } + txprof_dt_size = (int)atoi(str); + if (txprof_dt_size <= 0) { + EXIT(("Fcast: ERROR, invalid size for argument -p%s\n", optarg)) + } + if (rate > 0) { + txprof_rate = (int)((float)rate / + ((float)txprof_dt_size * 8.0)); + /* no less than 1 pkt/s */ + txprof_rate = max(1, txprof_rate); + } + /*PRINT(("fcast: txprof_dt_size=%d, rate=%d, txprof_rate=%d\n", txprof_dt_size, rate, txprof_rate))*/ + } else { + EXIT(("Fcast: ERROR, bad argument -p%s\n", optarg)) + } + break; + + + case 'R': + recursive = true; + break; + + case 'P': +#ifdef WIN32 + pause = 1; +#endif + break; + + case 'f': + if (!strncmp(optarg, "ec", 2)) { + if (isdigit((int)*(optarg+2))) + fec_ratio = (float)atof(optarg+2); + else + EXIT(("Fcast: ERROR, bad argument -f%s (NB: dont use space between -fec and value)\n", optarg)) + } else if (!strcmp(optarg, "orce")) { + overwrite = ALWAYS; + } else + EXIT(("Fcast: ERROR, bad argument -f%s\n", optarg)) + break; + case 'i': + if (!strcmp(optarg, "nt")) { + overwrite = PROMPT; + } else if (!strncmp(optarg, "f", 1)) { + /* process addr argument */ + char addr_str[256]; /* addr/name string */ + + if (*(optarg + 1) == '\0') { + EXIT(("Fcast: ERROR, bad argument -i%s: do not use extra space\n", optarg)) + } + strncpy(addr_str, optarg + 1, sizeof(addr_str)); + addr_str[255] = '\0'; + if (extract_addr(addr_str, &mcast_if_addr, 0) < 0) { + /* this is an interface name */ + mcast_if_name = (char *) + calloc(1, strlen(addr_str) + 1); + if (mcast_if_name == NULL) { + EXIT(("Fcast: ERROR, calloc failed during -i%s argument processing\n", optarg)) + } + strncpy(mcast_if_name, addr_str, strlen(addr_str)); + } + } else + EXIT(("Fcast: ERROR, bad argument -i%s\n", optarg)) + break; + case 'n': + if (!strcmp(optarg, "ever")) { + overwrite = NEVER; + } else + EXIT(("Fcast: ERROR, bad argument -n%s\n", optarg)) + break; +#ifdef WIN32 + case 1: + break; +#endif + default: + /* + * NB: getopt returns '?' when finding an + * unknown argument; avoid the following + * error msg in that case + */ + if (c != '?') + PRINT(("bad argument %c\n", c)) + Usage(argc, argv); + break; + } + } + + /* last arg is file name */ + ASSERT((argv[argc-1])) + if( mode == SEND ) + { + strncpy(fileparam, argv[argc-1], MAX_PATH+MAX_FILENAME); + } + +} + +#endif /* RM_PROTOCOL */ + + +/** + * Extract an IPv4 or IPv6 address from an address string or host name. + * Copies the address in the sockaddr structure. + * @param addr_string IPv4/IPv6 address string or host name. + * @param addr address of the pointer to sockaddr where to store + * the result. This function allocates the appropriate + * sockaddr_in/sockaddr_in6 structure. + * @param port port number in HOST byte order to store in sockaddr. + * @return 0 if OK, < 0 in case of error. + */ +static int +extract_addr (char *addr_string, + struct sockaddr **addr, + int port) +{ +// choose one resolver method according to what is available... +#if defined(LINUX) +#define HAS_GETHOSTBYNAME2 // GNU extension, ok on linux +#elif defined(SOLARIS) || defined(FREEBSD) //|| defined(WIN32) +#define HAS_GETIPNODEBYNAME // POSIX 1003.1-2001 version +#elif defined(WIN32) +#define HAS_NOTHING // Normal, it's WinSOCK ;-) +#endif + + + + +#ifdef HAS_GETHOSTBYNAME2 + struct hostent *hp; + + /* search for IPv4/IPv6 hostname or address first */ + hp = gethostbyname2(addr_string, AF_INET); + if (hp != NULL) { + struct sockaddr_in *sa; + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in)); + if (*addr == NULL) { + EXIT(("Fcast: ERROR, no memory\n")) + } + sa = (struct sockaddr_in*)*addr; + sa->sin_family = AF_INET; + sa->sin_port = htons(port); + memcpy(&(sa->sin_addr.s_addr), + hp->h_addr_list[0], + sizeof(struct in_addr)); + return 0; + } + hp = gethostbyname2(addr_string, AF_INET6); + if (hp != NULL) { + struct sockaddr_in6 *sa6; + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*) + calloc(1, sizeof(struct sockaddr_in6)); + if (*addr == NULL) { + EXIT(("Fcast: ERROR, no memory\n")) + } + sa6 = (struct sockaddr_in6*)*addr; + sa6->sin6_family = AF_INET6; + sa6->sin6_port = htons(port); + memcpy(&(sa6->sin6_addr), hp->h_addr_list[0], + sizeof(struct in6_addr)); + return 0; + } + /* everything failed */ + PRINT(("Fcast: ERROR, unknown host ""%s""\n", addr_string)) + return -1; +#endif // HAS_GETHOSTBYNAME2 +#ifdef HAS_GETIPNODEBYNAME + struct hostent *hp; + int err; + + /* search for IPv4 hostname or address first */ + hp = getipnodebyname(addr_string, AF_INET, AI_DEFAULT, &err); + //PRINT(("search for IPv4: returned x%x, err=%d\n", hp, err)) + if (hp != NULL) { + struct sockaddr_in *sa; + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in)); + if (*addr == NULL) { + EXIT(("Fcast: ERROR, no memory\n")) + } + sa = (struct sockaddr_in*)*addr; + sa->sin_family = AF_INET; + sa->sin_port = htons(port); + memcpy(&(sa->sin_addr.s_addr), + hp->h_addr_list[0], + sizeof(struct in_addr)); + return 0; + } + /* search for IPv6 hostname or address then */ + hp = getipnodebyname(addr_string, AF_INET6, AI_DEFAULT, &err); + //PRINT(("search for IPv6: returned x%x, err=%d\n", hp, err)) + if (hp != NULL) { + struct sockaddr_in6 *sa6; + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*) + calloc(1, sizeof(struct sockaddr_in6)); + if (*addr == NULL) { + EXIT(("Fcast: ERROR, no memory\n")) + } + sa6 = (struct sockaddr_in6*)*addr; + sa6->sin6_family = AF_INET6; + sa6->sin6_port = htons(port); + memcpy(&(sa6->sin6_addr), hp->h_addr_list[0], + sizeof(struct in6_addr)); + return 0; + } + /* everything failed */ + PRINT(("Fcast: ERROR, unknown host ""%s""\n", addr_string)) + return -1; +#endif // HAS_GETIPNODEBYNAME +#ifdef HAS_NOTHING + + if (ip_version ==4) + { + struct sockaddr_in *sa; + + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in)); + if (*addr == NULL) { + EXIT(("Fcast: ERROR, no memory\n")) + } + sa = (struct sockaddr_in*)*addr; + sa->sin_family = AF_INET; + sa->sin_port = htons(port); + /* + * addr must be in host byte order, but + * gethostbyname/inet_addr return network order + */ + if (isalpha((int)addr_string[0])) { + if (gethostbyname(addr_string) == NULL) { + PRINT(("Fcast: ERROR, unknown host ""%s""\n", addr_string)) + PRINT(("Fcast: did you specify the right IP version (with option -ipvn)?\n")) + free(*addr); + *addr = NULL; + return -1; + } + sa->sin_addr.s_addr = *(unsigned long *)((gethostbyname(addr_string))->h_addr); + } else { + sa->sin_addr.s_addr = inet_addr(addr_string); + } + } + else if (ip_version == 6) + { + struct sockaddr_in6 *sa6; + int len = sizeof(struct sockaddr_in6); + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*) + calloc(1, sizeof(struct sockaddr_in6)); + if (*addr == NULL) { + EXIT(("Fcast: ERROR, no memory\n")) + } + sa6 = (struct sockaddr_in6*)*addr; + sa6->sin6_family = AF_INET6; + if (WSAStringToAddress(addr_string, AF_INET6, NULL, (struct sockaddr*) sa6, &len) != 0) + { + EXIT(("Fcast: ERROR, WSAStringToAddress failed: %i\n", WSAGetLastError())) + } + sa6->sin6_port = htons(port); + } + return 0; +#endif // HAS_NOTHING +} + + +/* + * we received a SIGINT... + */ +static void +interrupted (void) +{ + static int abort_in_progress = 0; + + if (!abort_in_progress) { + abort_in_progress = 1; + PRINT(("fcast: aborted, call mcl_abort()\n")); + mcl_abort(id); + PRINT(("fcast: aborted, exit\n")); + exit(2); + } /* else do nothing */ +} diff --git a/fcast/fcast.h b/fcast/fcast.h new file mode 100644 index 0000000..67e184e --- /dev/null +++ b/fcast/fcast.h @@ -0,0 +1,149 @@ +/* $Id: fcast.h,v 1.10 2005/01/11 13:12:22 roca Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef WIN32 +#include +#include +#include +#include +#include "getopt.h" +#else +#if 0 +#if SOLARIS +#include /* see comment about readdir in fsend.c */ +#else +#include +#endif +#else +#include +#endif +#include +#include +#include +#include +#include +#include +#endif /* OS_DEP */ + + + +#include "../src/common/mcl_lib_api.h" +#include "checksum.h" +#include "metadata.h" +#include "macros.h" +#include "filemanage.h" +#include "fsend.h" +#include "frecv.h" + + +#if defined(LINUX) /* On Linux systems, signal handlers must be of __sighandler_t type */ +#define sighandler_t __sighandler_t +#elif defined(SOLARIS) || defined(IRIX) || defined(WIN32) +#define sighandler_t void (*)(int) +#elif defined(FREEBSD) +#define sighandler_t sig_t +#endif + + +/****** Constants ******/ + +/* + * Big files are all fragmented into fragments of size at most + * XXX_MAX_FRAGMENT_SIZE bytes. + * Try to make sure that the ALC object total size + * (i.e. XXX_MAX_FRAGMENT_SIZE + MAX_TRAILER_SIZE) is small enough to be + * encoded in a single ALC source block. + * XXX: this is specified statically, should be done by querying MCL + * + * Edit it as appropriate... + */ +#ifdef ALC +/* + * choose the appropriate size according to the FEC codec used by MCL + */ +#define RSE_MAX_FRAGMENT_SIZE (64*1024) // 65535 bytes +#define LDGM_MAX_FRAGMENT_SIZE (20*1024*1024) // 20 MB +#define NULL_FEC_MAX_FRAGMENT_SIZE (1*1024*1024) // 1 MB +/* + * Files larger than this size should be handled by LDGM-*, others by RSE. + * NB: RSE is more efficient than LDGM-* even if a few blocks are needed. + * Above a certain threshold, this is no longer true. + */ +#define RSE_LDGM_FILE_SIZE_THRESHOLD (20 * RSE_MAX_FRAGMENT_SIZE) + +#elif defined(NORM) + +#define RSE_MAX_FRAGMENT_SIZE (20*1024*1024) // use larger ADUs: eg. 20 MB +#define NULL_FEC_MAX_FRAGMENT_SIZE (20*1024*1024) // 20 MB + +#endif /* RM_PROTOCOL */ +#define MAX_TRAILER_SIZE 2050 // trailer appended to each fragment + + +/* other constants, do not edit */ +#define SEND 1 +#define RECV 2 + +#define OPTIMIZE_SPEED 1 +#define OPTIMIZE_SPACE 2 +#define OPTIMIZE_CPU 3 + + +/****** Globals ******/ + +extern int id; +extern int verbose; +extern int levels; +//extern unsigned long addr; +extern struct sockaddr *addr; +//extern unsigned long src_addr; +extern struct sockaddr *src_addr; +extern int port; +extern int ttl; +extern float fec_ratio; +extern int delivery_mode; + +extern int mode; +extern int optimode; +extern int speedmode; +extern int overwrite; +extern int single_layer; +extern int reuse_tx_buff; +extern char fileparam[MAX_PATH+MAX_FILENAME]; +extern bool recursive; +extern bool meta_object_mode; +extern int silent; +extern int tx_huge_file; + +/********************/ + diff --git a/fcast/fcast.vcproj b/fcast/fcast.vcproj new file mode 100644 index 0000000..f1da1e8 --- /dev/null +++ b/fcast/fcast.vcproj @@ -0,0 +1,248 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fcast/filemanage.c b/fcast/filemanage.c new file mode 100644 index 0000000..bededd5 --- /dev/null +++ b/fcast/filemanage.c @@ -0,0 +1,317 @@ +/* $Id: filemanage.c,v 1.2 2004/05/26 07:36:03 roca Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * filemanage.c + * + * Tools for Directories listing and files management... + */ + +#include "fcast.h" + + +int FileExist( const char *filepath) +{ + FILE *check; + check = fopen(filepath, "r"); + + ASSERT(filepath!=NULL); + + if( check == NULL) + return 0; + else + { + fclose(check); + return 1; + } + +} + + + +int IsDirDots (const char *path) +{ + return (path[0] == '\0' + || (path[0] == '.' && (path[1] == '\0' + || (path[1] == '.' && path[2] == '\0')))); +} + + + +void GetFileName( char *filepath, char *filename ) +{ + char *token1, *token2; + + ASSERT( (filepath != NULL) + && (filename != NULL) + && (strlen(filepath)<=(MAX_PATH+MAX_FILENAME)) ) + + token1 = filepath; + token2 = strpbrk(token1, "/\\"); + while( token2 ) + { + token1 = token2+1; + token2 = strpbrk(token1, "/\\"); + } + strncpy(filename, token1, MAX_FILENAME); +} + + +void GetFileBase( char *filepath, char *filebase ) +{ + char *token1, *token2; + + ASSERT( (filepath != NULL) + && (filebase != NULL) + && (strlen(filepath)<=(MAX_PATH+MAX_FILENAME)) ) + + token1 = filepath; + token2 = strpbrk(token1, "/\\"); + while( token2 ) + { + token1 = token2+1; + token2 = strpbrk(token1, "/\\"); + } + if(token1 == filepath) + strcpy(filebase, "./"); + else + { + strncpy(filebase, filepath, (strlen(filepath)-strlen(token1))); + filebase[strlen(filepath)-strlen(token1)] = '\0'; + } + +} + + + +void GetFileBaseWithoutPrefix( char *filepath, char *filebase ) +{ + char *token1, *token2; + unsigned int path_prefix = 0; + unsigned int BaseLen = 0; + + ASSERT( (filepath != NULL) + && (filebase != NULL) + && (strlen(filepath)<=(MAX_PATH+MAX_FILENAME)) ) + + token1 = filepath; + token2 = strpbrk(token1, "/\\"); + while( token2 ) + { + token1 = token2+1; + token2 = strpbrk(token1, "/\\"); + } + if(token1 == filepath) + strcpy(filebase, "./"); + else + { while(filepath[path_prefix] == '/' || filepath[path_prefix] == '\\' || filepath[path_prefix] == '.' ) + path_prefix++; + BaseLen = strlen(filepath) - strlen(token1) - path_prefix; + strncpy(filebase, filepath+path_prefix, BaseLen); + filebase[BaseLen] = '\0'; + } + +} + + +int CheckWriteContext( char *filepath, int mode) +{ int writeIt = 0; + + if( FileExist(filepath) ) + { + char c = '\0'; + switch (mode) + { + case ALWAYS: + writeIt = 1; + break; + case NEVER: + writeIt = 0; + break; + case PROMPT: + read: + PRINT(("\nFile \"%s\" exists, overwrite? [y/n] ", filepath)) + fflush(stdin); + scanf("%c", &c); + if(c == 'y') + writeIt = 1; + else if(c == 'n') + writeIt = 0; + else + goto read; + break; + default: + PRINT(("CheckWriteContext: ERROR, Unknown overwrite mode")) + writeIt = 0; + break; + } + } + else + { + struct stat stats; + char *DirName_buf; + char *DirName; + char *Prefix_buf; + char *Prefix; + + if (!(DirName_buf = DirName = (char*)malloc(MAX_PATH)) || + !(Prefix_buf = Prefix = (char*)malloc(MAX_PATH))) { + PRINT(("CheckWriteContext: ERROR, No Memory")) + exit(1); + } + GetFileBase(filepath, DirName); + if(DirName[0] == '/' || DirName[0] == '\\') + strcpy(Prefix, "\0"); + else + strcpy(Prefix, ".\0"); + + DirName = strtok( DirName, "/\\"); + while( DirName ) + { + strcat(Prefix, "/"); + strcat(Prefix, DirName); + if(stat(Prefix, &stats) != -1) + { + if( !(stats.st_mode & S_IFDIR )) + { + PRINT(("Unable to create directory %s, because a file with the same name already exists\n", Prefix)) + goto end; + } + } + else + { + PRINT(("Creating directory %s\n", Prefix)) +#ifdef WIN32 + if(mkdir( Prefix ) <0 ) +#else + if(mkdir( Prefix, 0755) <0 ) +#endif + { + EXIT(("%s : Unable to create directory\n", Prefix)) + } + } + DirName = strtok( NULL, "/\\"); + } + free(DirName_buf); + free(Prefix_buf); + writeIt = 1; + } + +end: return writeIt; +} + + + + +void FFileInsert(ppFFile p_filelist, FFile newfile ) +{ + pFFile List = *p_filelist; + + if (List == NULL) { + if (!(*p_filelist = (FFile *)malloc(sizeof(FFile)))) { + EXIT(("Error: Cannot alloc memory!\n")) + } + List = *p_filelist; + } + else + { + while (List->next != NULL) { + List = List->next; + } + if (!(List->next = (FFile *)malloc(sizeof(FFile)))) { + EXIT(("Error: Cannot alloc memory!\n")) + } + List = List->next; + } + + strncpy((List)->fullname, newfile.fullname, MAX_PATH+MAX_FILENAME ); + List->writeIt = newfile.writeIt; + List->fd = newfile.fd; + List->filesize = newfile.filesize; + List->nbFragTot = newfile.nbFragTot; + List->nbFragRcvd = newfile.nbFragRcvd; + List->next = NULL; +} + + + +pFFile FFileFind( const char *fullname, pFFile filelist ) +{ + pFFile found = NULL; + pFFile listloop = filelist; + + while(listloop != NULL) + { + if( !strcmp(listloop->fullname, fullname) ) { + found = listloop; + break; + } + listloop = listloop->next; + } + return found; +} + + +void FFileRemove ( const char *fullname, ppFFile p_filelist ) +{ + pFFile found = FFileFind( fullname, *p_filelist ); + pFFile listloop = *p_filelist; + + if (found != NULL && listloop != NULL) + { + if(listloop == found) + { + *p_filelist = listloop->next; + free(listloop); + } + else + { + while(listloop->next != found) + { + listloop = listloop->next; + } + + listloop->next = found->next; + free(found); + } + } + else + { + EXIT(("Error: FFile %s not found!\n", fullname)) + } + +} + +void FFilePrintList(pFFile FFList) +{ + pFFile listloop = FFList; + + PRINT(("File fragments received:\n")) + while(listloop != NULL) + { + PRINT(("\t%s (%d/%d)\n", listloop->fullname, listloop->nbFragRcvd, listloop->nbFragTot)) + listloop = listloop->next; + } + PRINT(("\n")) +} + diff --git a/fcast/filemanage.h b/fcast/filemanage.h new file mode 100644 index 0000000..fda4c92 --- /dev/null +++ b/fcast/filemanage.h @@ -0,0 +1,75 @@ +/* $Id: filemanage.h,v 1.1.1.1 2003/09/03 12:45:41 chneuman Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * filemanage.h + * + * Tools for Directories listing and files management... + */ + +#include +#include +#include +#include +#include + + + +#ifdef WIN32 +#include +#endif + +#ifndef MAX_PATH +#define MAX_PATH 1024 +#endif + +#define MAX_FILENAME 512 + +#define PROMPT 1 +#define NEVER 2 +#define ALWAYS 3 + +typedef struct FFileStruct +{ + char fullname[MAX_PATH+MAX_FILENAME];// Full path+name + int writeIt; // Shall we write it or not? + int fd; // File descriptor + long filesize; // File size in Bytes + int nbFragTot; // Total number of fragments for this file. + int nbFragRcvd; // number of fragments already received. + struct FFileStruct *next; // pointer to the next File (if any). +} FFile, *pFFile, **ppFFile; + + +int FileExist ( const char *filepath ); +int IsDirDots ( const char *path); +void GetFileName ( char *filepath, char *filename ); +void GetFileBase ( char *filepath, char *filebase ); +void GetFileBaseWithoutPrefix ( char *filepath, char *filebase ); +int CheckWriteContext ( char *filepath, int mode ); + +void FFileInsert(ppFFile p_filelist, FFile newfile ); +pFFile FFileFind ( const char *fullname, pFFile filelist ); +void FFileRemove ( const char *fullname, ppFFile p_filelist ); +void FFilePrintList(pFFile FFList); + diff --git a/fcast/frecv.c b/fcast/frecv.c new file mode 100644 index 0000000..47fc76f --- /dev/null +++ b/fcast/frecv.c @@ -0,0 +1,307 @@ +/* $Id: frecv.c,v 1.11 2005/03/23 14:05:00 roca Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * frecv.c + * + * fcast receiver side functions + */ +#include "fcast.h" + + +void FcastRecv(void) +{ + int Bytes_received = 0; +// int received = 0; +#if defined(ALC) + int mcl_option; + + if (optimode == OPTIMIZE_SPACE) { + mcl_option = 1; + if (mcl_ctl(id, MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, (void*)&mcl_option, + sizeof(mcl_option))) + EXIT(("mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI failed\n")) + mcl_option = 0; + if (mcl_ctl(id, MCL_OPT_POSTPONE_FEC_DECODING, + (void*)&mcl_option, sizeof(mcl_option))) { + /* non critical... ignore! */ + //EXIT(("mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING failed\n")) + } + + } else if (optimode == OPTIMIZE_SPEED) { + mcl_option = 1; + if (mcl_ctl(id, MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, (void*)&mcl_option, + sizeof(mcl_option))) + EXIT(("mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI failed\n")) + mcl_option = 0; + if (mcl_ctl(id, MCL_OPT_POSTPONE_FEC_DECODING, + (void*)&mcl_option, sizeof(mcl_option))) { + /* non critical... ignore! */ + //EXIT(("mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING failed\n")) + } + } else if (optimode == OPTIMIZE_CPU) { + mcl_option = 0; + if (mcl_ctl(id, MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, (void*)&mcl_option, + sizeof(mcl_option))) + EXIT(("mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI failed\n")) + mcl_option = 1; + if (mcl_ctl(id, MCL_OPT_POSTPONE_FEC_DECODING, + (void*)&mcl_option, sizeof(mcl_option))) { + /* + * non critical... ignore! + * for instance, this is only valid if RSE is used, + * but does not apply to LDPC/LDGM + */ + //EXIT(("mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING failed\n")) + } + } else { + EXIT(("FATAL ERROR: invalid optimization mode!")) + } +#endif /* RM_PROTOCOL */ + + if (src_addr > 0) { + /* in host format! */ + if (mcl_ctl(id, MCL_OPT_SRC_ADDR, (void*)&src_addr, + sizeof(src_addr))) + EXIT(("mcl_ctl: MCL_OPT_SRC_ADDR failed\n")) + } + + PRINT(("Waiting for data...\n")) + + /* and now receive all... */ + Bytes_received = RecvFiles(); + + mcl_close(id); + PRINT(("\nFcastRecv completed, %d bytes received\n", Bytes_received)) +} + + +int RecvFiles (void) +{ + char *buf_file = NULL; /* buffer for recv'd fragment */ + unsigned char BlockTmp4[4]; + char file_path[MAX_FILENAME + MAX_PATH]; + int len = 0; + char *Trailer = NULL; + unsigned short global_sum = 0; + unsigned long trailerlength = 0; + meta_t *MetaList = NULL; + meta_t *lpMetaData = NULL; + int CurrFrag = 0; + int offset = 0; + int received = 0; + long FragLength = 0; + pFFile PartialFiles = NULL; + pFFile ThisFile; +#if defined(NORM) + int max_fragment_size; /* Big files are fragmented into + fragments of this size */ +#elif defined(ALC) + struct mcl_msghdr mh; /* for mcl_recvsmg */ +#endif + + /* + * Receive _ALL_ objects... + */ +#if defined(NORM) + /* recvmsg is not yet implemented, so use a static buffer of + * maximum object length */ + /* determine the maximum fragment size (pessimistic evaluation that + * does not take the FEC actually used into account) */ + max_fragment_size = RSE_MAX_FRAGMENT_SIZE; + //max_fragment_size = max(max_fragment_size, LDGM_MAX_FRAGMENT_SIZE); + max_fragment_size = max(max_fragment_size, NULL_FEC_MAX_FRAGMENT_SIZE); + + /* Objects contain a file (or fragment), with its associated trailer + * and checksum... */ + if(!(buf_file = (char*)malloc(max_fragment_size + MAX_TRAILER_SIZE))) { + EXIT(("Fcast ERROR: Cannot alloc memory!\n")) + } + + /* Receiving all objects... */ + while((len = mcl_recv(id, buf_file, + max_fragment_size + MAX_TRAILER_SIZE)) != -1) { + +#elif defined(ALC) + + /* recvmsg is used to identify the exact object length */ + memset((void*)&mh, 0, sizeof(mh)); + while ((len = mcl_recvmsg(id, &mh, + MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT)) != -1) { + /* Objects contain a file (or fragment), with its associated + * trailer and checksum... */ + if(!(buf_file = (char*)malloc(len))) { + EXIT(("Fcast ERROR: Cannot alloc memory (%d bytes needed)!\n", len)) + } + len = mcl_recv(id, buf_file, len); + if (len < 0) { + EXIT(("Fcast ERROR: mcl_recv failed\n")) + } +#endif /* RM_PROTOCOL */ +#ifdef DEBUG + PRINT(("New Object Received (%d Bytes)\n", len)) +#endif + + /* Compute the checksum and check if GlobalSum is 0xFFFF + * (i.e. checksum == 0) */ + global_sum = ComputeSum( (unsigned short*)buf_file, len, NULL ); + if ( global_sum != 0xFFFF) { + //EXIT(("Fcast ERROR: Invalid Checksum!!! (sum 0x%X)\n", global_sum)) + printf("Fcast ERROR: Invalid Checksum!!! (sum 0x%X)\n", global_sum); + } + + /* Get the Trailer Infos */ + memcpy( BlockTmp4, (buf_file+len-8), 4); + trailerlength = BUFFER_TO_INT32(BlockTmp4); +#ifdef DEBUG + PRINT(("\n)=> Trailer infos: %ld Bytes.\n", trailerlength)) +#endif + + if (!(Trailer = (char*)malloc(trailerlength + 1))) { + EXIT(("Error: Cannot alloc memory!\n")) + } + memcpy( Trailer, (buf_file +len -8 -trailerlength), trailerlength ); + Trailer[trailerlength]= '\0'; + + /* Parse All Metas from the Trailer */ + MetaList = ParseTrailer(Trailer); + free(Trailer); + GetFilePathFromMeta(MetaList, file_path); + + if( (FragLength = GetMetaLength(MetaList)) != (long)(len -8 -trailerlength) ) + { + EXIT(("Fcast ERROR: Size of fragment received and \"Content-length\" value don't match! (%ld!=%ld)\n",lpMetaData->value, GetMetaLength(MetaList))) + } + + FFilePrintList(PartialFiles); + + ThisFile = FFileFind(file_path, PartialFiles); + + if (ThisFile == NULL) { + /* + * First fragment for this FILE + */ + FFile NewFile; + strncpy(NewFile.fullname, file_path, MAX_PATH+MAX_FILENAME ); +#ifdef DEBUG + PRINT(("New File received: %s\n", NewFile.fullname)) +#endif + PrintMetaList(MetaList); + NewFile.writeIt = CheckWriteContext(NewFile.fullname, overwrite); + if(NewFile.writeIt) + { +#ifdef WIN32 + if ((NewFile.fd = open(NewFile.fullname, + O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, _S_IWRITE)) < 0) +#else + if ((NewFile.fd = open(NewFile.fullname, + O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU)) < 0) +#endif + { + EXIT(("Error while opening file \"%s\"\n", NewFile.fullname)) + } + } + NewFile.filesize = GetMetaFilesize(MetaList); + NewFile.nbFragRcvd = 1; + NewFile.next = NULL; + GetMetaFragment(MetaList, &CurrFrag, &NewFile.nbFragTot); + FFileInsert(&PartialFiles, NewFile); + ThisFile = FFileFind(file_path, PartialFiles); + } else { + /* + * We've already received fragment(s) from this file + */ + int nbfrag; + ASSERT(!strcmp(ThisFile->fullname, file_path)) +#ifdef DEBUG + PRINT(("File %s already in database...\n", + ThisFile->fullname)) +#endif + /* ASSERT(ThisFile->fd != 0) */ + ASSERT(ThisFile->filesize == GetMetaFilesize(MetaList)) + ASSERT(ThisFile->nbFragRcvd >0 ) + GetMetaFragment(MetaList, &CurrFrag, &nbfrag); + ASSERT(ThisFile->nbFragTot == nbfrag) + ThisFile->nbFragRcvd++; + } + + ASSERT(ThisFile != NULL) + ASSERT(ThisFile->nbFragRcvd<= ThisFile->nbFragTot) + + if (ThisFile->writeIt) { + PRINT(("Processing fragment %d of file %s (Total=%d / Rcvd=%d)\n", CurrFrag, ThisFile->fullname, ThisFile->nbFragTot, ThisFile->nbFragRcvd)) + offset = GetMetaOffset(MetaList); +#ifdef DEBUG + PRINT(("\tWriting %ld bytes at offset %d\n", FragLength, offset)) +#endif + + if (lseek((int)ThisFile->fd, (long)offset, SEEK_SET) < 0) + EXIT(("Error: lseek failed\n")) + if (write((int)ThisFile->fd, buf_file, FragLength) < 0) + EXIT(("mclrecv: write failed\n")) + + if (ThisFile->nbFragRcvd == ThisFile->nbFragTot) + { + // This File is complete! + PRINT(("Finished receiving file \"%s\" (%ld Bytes).\n", ThisFile->fullname, ThisFile->filesize)) + ASSERT(ThisFile->fd != 0) + close(ThisFile->fd); + FFileRemove(ThisFile->fullname, &PartialFiles); + } + received += len; + + } else { + /* + * This is a skipped file + */ + PRINT(("Skipping fragment %d of file %s (Total=%d / Rcvd=%d) (file already exists)\n", CurrFrag, ThisFile->fullname, ThisFile->nbFragTot, ThisFile->nbFragRcvd)) + + if (ThisFile->nbFragRcvd == ThisFile->nbFragTot) { + /* + * This File is complete! + */ + PRINT(("File \"%s\" -> All fragments have been skipped (file already exists).\n", ThisFile->fullname)) + //ASSERT(ThisFile->fd == 0) + FFileRemove(ThisFile->fullname, &PartialFiles); + } + + } + DestroyMetalist(MetaList); +#ifdef ALC + /* free this buffer, since next object may be significantly + * shorter or larger */ + free(buf_file); + buf_file = NULL; +#endif + } + + if (PartialFiles != NULL) { + // When loop ends, all files must be completed! + FFilePrintList(PartialFiles); + EXIT(("Fcast ERROR: MCL session closed and there are missing fragments\n")) + // TODO display missing files/fragment + } + + return received; +} + diff --git a/fcast/frecv.c.org b/fcast/frecv.c.org new file mode 100644 index 0000000..965f96e --- /dev/null +++ b/fcast/frecv.c.org @@ -0,0 +1,295 @@ +/* $Id: frecv.c,v 1.4 2004/02/18 14:51:50 roca Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * frecv.c + * + * fcast receiver side functions + */ +#include "fcast.h" + + + + +void FcastRecv(void) +{ + int Bytes_received = 0; +// int received = 0; +#if defined(ALC) + int mcl_option; + + if (optimode == OPTIMIZE_SPACE) + { + mcl_option = 1; + if (mcl_ctl(id, MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, (void*)&mcl_option, + sizeof(mcl_option))) + EXIT(("mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI failed\n")) + mcl_option = 0; + if (mcl_ctl(id, MCL_OPT_POSTPONE_FEC_DECODING, + (void*)&mcl_option, sizeof(mcl_option))) { + /* non critical... ignore! */ + //EXIT(("mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING failed\n")) + } + + } + else if (optimode == OPTIMIZE_SPEED) + { + mcl_option = 1; + if (mcl_ctl(id, MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, (void*)&mcl_option, + sizeof(mcl_option))) + EXIT(("mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI failed\n")) + mcl_option = 0; + if (mcl_ctl(id, MCL_OPT_POSTPONE_FEC_DECODING, + (void*)&mcl_option, sizeof(mcl_option))) { + /* non critical... ignore! */ + //EXIT(("mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING failed\n")) + } + } + else if (optimode == OPTIMIZE_CPU) + { + mcl_option = 0; + if (mcl_ctl(id, MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, (void*)&mcl_option, + sizeof(mcl_option))) + EXIT(("mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI failed\n")) + mcl_option = 1; + if (mcl_ctl(id, MCL_OPT_POSTPONE_FEC_DECODING, + (void*)&mcl_option, sizeof(mcl_option))) { + /* + * non critical... ignore! + * for instance, this is only valid if RSE is used, + * but does not apply to LDPC/LDGM + */ + //EXIT(("mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING failed\n")) + } + } + else + { + EXIT(("FATAL ERROR: invalid optimization mode!")) + } +#endif /* RM_PROTOCOL */ + + if (src_addr > 0) /* in host format! */ + { + if (mcl_ctl(id, MCL_OPT_SRC_ADDR, (void*)&src_addr, + sizeof(src_addr))) + EXIT(("mcl_ctl: MCL_OPT_SRC_ADDR failed\n")) + } + + PRINT(("Waiting for data...\n")) + + /* and now receive all... */ + Bytes_received = RecvFiles(); + + mcl_close(id); + PRINT(("\nFcastRecv completed, %d bytes received\n", Bytes_received)) +} + + + +int RecvFiles(void) +{ + char *buf_file = NULL; /* buffer for recv'd fragment */ + unsigned char BlockTmp4[4]; + char file_path[MAX_FILENAME + MAX_PATH]; + int len = 0; + char *Trailer = NULL; + unsigned short global_sum = 0; + unsigned long trailerlength = 0; + meta_t *MetaList = NULL; + meta_t *lpMetaData = NULL; + int CurrFrag = 0; + int offset = 0; + int received = 0; + long FragLength = 0; + pFFile PartialFiles = NULL; + pFFile ThisFile; + int max_fragment_size; /* Big files are fragmented into + fragments of this size */ + + + /* determine the maximum fragment size (pessimistic evaluation that + * does not take FEC used into account) */ + max_fragment_size = RSE_MAX_FRAGMENT_SIZE; +#ifdef ALC + max_fragment_size = max(max_fragment_size, LDGM_MAX_FRAGMENT_SIZE); +#endif /* RM_PROTOCOL */ + max_fragment_size = max(max_fragment_size, NULL_FEC_MAX_FRAGMENT_SIZE); + + /* Objects contain a file (or fragment), with its associated trailer + * and checksum... */ + if(!(buf_file = (char*)malloc(max_fragment_size + MAX_TRAILER_SIZE))) { + EXIT(("Error: Cannot alloc memory!\n")) + } + + /* Receiving ALL Object... */ + while((len = mcl_recv(id, buf_file, max_fragment_size + MAX_TRAILER_SIZE)) != -1) + { +#ifdef DEBUG + PRINT(("New Object Received (%d Bytes)\n", len)) +#endif + +#if 0 + /* Realloc the Buffer to fit our needs */ + if (!(buf_file = (char*)realloc(buf_file, len))) { + EXIT(("Error: Cannot realloc memory (RecvFiles)!\n")) } +#endif + + /* Compute the Checksum and check if GlobalSum is 0xFFFF (checksum == 0) */ + global_sum = ComputeSum( (unsigned short*)buf_file, len, NULL ); + if ( global_sum != 0xFFFF) + { + EXIT(("Fcast ERROR: Invalid Checksum!!! (sum 0x%X)\n", global_sum)) + } + + /* Get the Trailer Infos */ + memcpy( BlockTmp4, (buf_file+len-8), 4); + trailerlength = BUFFER_TO_INT32(BlockTmp4); +#ifdef DEBUG + PRINT(("\n)=> Trailer infos: %ld Bytes.\n", trailerlength)) +#endif + + if (!(Trailer = (char*)malloc(trailerlength + 1))) { + EXIT(("Error: Cannot alloc memory!\n")) + } + memcpy( Trailer, (buf_file +len -8 -trailerlength), trailerlength ); + Trailer[trailerlength]= '\0'; + + /* Parse All Metas from the Trailer */ + MetaList = ParseTrailer(Trailer); + free(Trailer); + GetFilePathFromMeta(MetaList, file_path); + + if( (FragLength = GetMetaLength(MetaList)) != (long)(len -8 -trailerlength) ) + { + EXIT(("Fcast ERROR: Size of fragment received and \"Content-length\" value don't match! (%ld!=%ld)\n",lpMetaData->value, GetMetaLength(MetaList))) + } + + FFilePrintList(PartialFiles); + + ThisFile = FFileFind(file_path, PartialFiles); + + if(ThisFile == NULL) /* First fragment for this FILE */ + { + FFile NewFile; + strncpy(NewFile.fullname, file_path, MAX_PATH+MAX_FILENAME ); +#ifdef DEBUG + PRINT(("New File received: %s\n", NewFile.fullname)) +#endif + PrintMetaList(MetaList); + NewFile.writeIt = CheckWriteContext(NewFile.fullname, overwrite); + if(NewFile.writeIt) + { +#ifdef WIN32 + if ((NewFile.fd = open(NewFile.fullname, + O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, _S_IWRITE)) < 0) +#else + if ((NewFile.fd = open(NewFile.fullname, + O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU)) < 0) +#endif + { + EXIT(("Error while opening file \"%s\"\n", NewFile.fullname)) + } + } + NewFile.filesize = GetMetaFilesize(MetaList); + NewFile.nbFragRcvd = 1; + NewFile.next = NULL; + GetMetaFragment(MetaList, &CurrFrag, &NewFile.nbFragTot); + FFileInsert(&PartialFiles, NewFile); + ThisFile = FFileFind(file_path, PartialFiles); + } + else /* We've already received fragment(s) from this file */ + { + int nbfrag; + ASSERT(!strcmp(ThisFile->fullname, file_path)) +#ifdef DEBUG + PRINT(("File %s already in database...\n", ThisFile->fullname)) +#endif +/* ASSERT(ThisFile->fd != 0) */ + ASSERT(ThisFile->filesize == GetMetaFilesize(MetaList)) + ASSERT(ThisFile->nbFragRcvd >0 ) + GetMetaFragment(MetaList, &CurrFrag, &nbfrag); + ASSERT(ThisFile->nbFragTot == nbfrag) + ThisFile->nbFragRcvd++; + } + + ASSERT(ThisFile != NULL) + ASSERT(ThisFile->nbFragRcvd<= ThisFile->nbFragTot) + + if (ThisFile->writeIt) + { + PRINT(("Processing fragment %d of file %s (Total=%d / Rcvd=%d)\n", CurrFrag, ThisFile->fullname, ThisFile->nbFragTot, ThisFile->nbFragRcvd)) + offset = GetMetaOffset(MetaList); +#ifdef DEBUG + PRINT(("\tWriting %ld bytes at offset %d\n", FragLength, offset)) +#endif + + if (lseek((int)ThisFile->fd, (long)offset, SEEK_SET) < 0) + EXIT(("Error: lseek failed\n")) + if (write((int)ThisFile->fd, buf_file, FragLength) < 0) + EXIT(("mclrecv: write failed\n")) + + if (ThisFile->nbFragRcvd == ThisFile->nbFragTot) + { + // This File is complete! + PRINT(("Finished receiving file \"%s\" (%ld Bytes).\n", ThisFile->fullname, ThisFile->filesize)) + ASSERT(ThisFile->fd != 0) + close(ThisFile->fd); + FFileRemove(ThisFile->fullname, &PartialFiles); + } + received += len; + + } + else + { + /* This is a skipped file */ + PRINT(("Skipping fragment %d of file %s (Total=%d / Rcvd=%d) (file already exists)\n", CurrFrag, ThisFile->fullname, ThisFile->nbFragTot, ThisFile->nbFragRcvd)) + + if(ThisFile->nbFragRcvd == ThisFile->nbFragTot) // This File is complete! + { + PRINT(("File \"%s\" -> All fragments have been skipped (file already exists).\n", ThisFile->fullname)) + //ASSERT(ThisFile->fd == 0) + FFileRemove(ThisFile->fullname, &PartialFiles); + } + + } + DestroyMetalist(MetaList); + +#if 0 + if (!(buf_file = (char*)realloc(buf_file, max_fragment_size + MAX_TRAILER_SIZE))) { + EXIT(("Error: Cannot realloc memory (RecvFiles)!\n")) + } +#endif + } + + if (PartialFiles != NULL) // When loop ends, all files must be completed! + { + FFilePrintList(PartialFiles); + EXIT(("Fcast ERROR: MCL session closed and there are missing fragments\n")) + // TODO display missing files/fragment + } + + if(buf_file) free(buf_file); + + return received; +} + diff --git a/fcast/frecv.h b/fcast/frecv.h new file mode 100644 index 0000000..8f3f35a --- /dev/null +++ b/fcast/frecv.h @@ -0,0 +1,31 @@ +/* $Id: frecv.h,v 1.2 2004/07/16 14:55:29 roca Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * frecv.h + * + * fcast receiver side functions headers + */ + +void FcastRecv (void); +int RecvOneFile (void); +int RecvFiles (void); diff --git a/fcast/fsend.c b/fcast/fsend.c new file mode 100644 index 0000000..3d8e015 --- /dev/null +++ b/fcast/fsend.c @@ -0,0 +1,660 @@ +/* $Id: fsend.c,v 1.19 2005/01/11 13:12:22 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * fsend.c + * + * fcast sender side functions + */ +#include "fcast.h" + + +/* + * Local variables + */ + +/* available FEC codecs and associated information */ +typedef struct fec_codec_info { + int available; /* boolean */ + int max_block_size; /* raw value as defined by MCL */ + int max_fragment_size; /* big files are fragmented into */ + /* fragments of this size */ +} fec_codec_info_t; + +fec_codec_info_t NULL_FEC_info; +fec_codec_info_t RSE_FEC_info; +fec_codec_info_t LDGM_STAIRCASE_FEC_info; +fec_codec_info_t LDGM_TRIANGLE_FEC_info; + + + +void FcastSend (void) +{ + int Bytes_sent = 0; +#if defined(ALC) + int mcl_option; +#endif /* RM_PROTOCOL */ + + /* Determine available FEC codes and init. associated info struct */ + FindAvailableFEC(); + /* Determine the appropriate modes */ +#if defined(ALC) + /* + * NB: always use LCT1 now, in all cases... + */ + mcl_option = MCL_SCHED_LCT1; + if (mcl_ctl(id, MCL_OPT_SCHED, (void*)&mcl_option, sizeof(mcl_option))) { + EXIT(("Fcast: mcl_ctl MCL_OPT_SCHED failed for LCT1\n")) + } + if (optimode == OPTIMIZE_SPACE) { + mcl_option = MCL_SCHED_PARTIALLY_MIXED_ORDER; + if (mcl_ctl(id, MCL_OPT_OBJ_SCHED, (void*)&mcl_option, + sizeof(mcl_option))) + EXIT(("Fcast: mcl_ctl MCL_OPT_SCHED failed\n")) + } else if (optimode == OPTIMIZE_SPEED) { + mcl_option = MCL_SCHED_MIXED_ORDER; + if (mcl_ctl(id, MCL_OPT_OBJ_SCHED, (void*)&mcl_option, sizeof(mcl_option))) + EXIT(("Fcast: mcl_ctl MCL_OPT_OBJ_SCHED failed\n")) + } else if (optimode == OPTIMIZE_CPU) { + mcl_option = MCL_SCHED_MIXED_ORDER; + if (mcl_ctl(id, MCL_OPT_OBJ_SCHED, (void*)&mcl_option, sizeof(mcl_option))) + EXIT(("Fcast: mcl_ctl MCL_OPT_OBJ_SCHED failed\n")) + } else { + EXIT(("Fcast: ERROR, invalid optimization mode!")) + } +#elif defined(NORM) + /* no equivalent */ +#endif /* RM_PROTOCOL */ + + /* + mcl_option = 1; + mcl_ctl(id, MCL_OPT_REUSE_APPLI_TX_BUFFER, (void*)&mcl_option, + sizeof(mcl_option)); + */ + /* + * Now send the file(s) + */ +#if defined(ALC) + if(mcl_ctl(id, MCL_OPT_KEEP_DATA, NULL, 0)) + EXIT(("Fcast: mcl_ctl KEEP_DATA failed\n")) + if (recursive) { + if (meta_object_mode) { + if (mcl_ctl(id, MCL_OPT_KEEP_META_OBJECT, NULL, 0)) + EXIT(("Fcast: mcl_ctl KEEP_META_OBJECT failed\n")) + } + Bytes_sent = RecursiveSend(fileparam); + if (meta_object_mode) { + fec_codec_info_t *codec_info; + /* + * If the meta_object mode is set, then select the + * FEC codec based on the total aggregate length... + * This is this call that will determine the effective + * codec used, no matter what may have been issued + * before. Usually the codec will be LDGM_XXX since + * the total aggregated length is usually larger than + * the maximum RSE block size threshold. + */ + codec_info = ChooseFEC(Bytes_sent); + if (mcl_ctl(id, MCL_OPT_PUSH_META_OBJECT, NULL, 0)) + EXIT(("Fcast: mcl_ctl PUSH_META_OBJECT failed\n")) + } + } else { + Bytes_sent = SendThisFile(fileparam); + } + if (mcl_ctl(id, MCL_OPT_PUSH_DATA, NULL, 0)) + EXIT(("Fcast: mcl_ctl PUSH_DATA failed\n")) +#elif defined(NORM) + if (recursive) { + Bytes_sent = RecursiveSend(fileparam); + } else { + Bytes_sent = SendThisFile(fileparam); + } +#endif /* RM_PROTOCOL */ + /* + * Finished, close the MCL session. + */ + mcl_close(id); + PRINT(("\nFcastSend completed. %d bytes sent\n", Bytes_sent)) +} + + +#ifdef WIN32 /* directory parsing is OS dependant */ + + +int RecursiveSend (char* Path) +{ + + HANDLE dirp = NULL; + WIN32_FIND_DATA entry; + unsigned int total_sent = 0; + char FullName[MAX_PATH + MAX_FILENAME]; + char FindString[MAX_PATH]; + + strcpy(FindString, Path); + strcat(FindString, "\\*"); + + dirp = FindFirstFile(FindString, &entry); + + if (dirp == INVALID_HANDLE_VALUE) { + EXIT(("Fcast: ERROR, in recursive mode, the given parameter MUST BE a valid directory name\nAborting...\n")) + } + + if (!IsDirDots (entry.cFileName)) { + strcpy(FullName, Path); + if(FullName[strlen(FullName)-1] == '\\') + FullName[strlen(FullName)-1] = '/'; + + if(FullName[strlen(FullName)-1] != '/') + strcat(FullName,"/"); + + strcat(FullName, entry.cFileName); + + if( entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + ASSERT((strcmp(Path,FullName))) + PRINT(("Entering Directory %s\n", FullName)) + total_sent+= RecursiveSend (FullName); + } else { + PRINT(("\nSending File %s\n", FullName)) + total_sent += SendThisFile (FullName); + } + } + + while ( FindNextFile(dirp, &entry) ) { + if (IsDirDots (entry.cFileName)) + continue; + + strcpy(FullName, Path); + if(FullName[strlen(FullName)-1] == '\\') + FullName[strlen(FullName)-1] = '/'; + + if(FullName[strlen(FullName)-1] != '/') + strcat(FullName,"/"); + + strcat(FullName, entry.cFileName); + + if( entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + ASSERT((strcmp(Path,FullName))) + PRINT(("Entering Directory %s\n", FullName)) + total_sent+= RecursiveSend (FullName); + } else { + PRINT(("\nSending File %s\n", FullName)) + total_sent += SendThisFile(FullName); + } + } + FindClose(dirp); + return total_sent; +} + + +#else /* UNIX case */ + + +int RecursiveSend (char* Path) +{ + unsigned int total_sent = 0; + struct dirent *entry; + struct stat stats; + char FullName[MAX_PATH + MAX_FILENAME]; + DIR *dirp; + + if ((dirp = opendir (Path)) == NULL) { + perror(Path); + EXIT(("RecursiveSend: ERROR, opendir failed\n")) + } + + /* + For SOLARIS users: + Why doesn't readdir work? It chops the first two characters of + all filenames. + + You're probably linking with libucb and didn't read question + 6.18. (Readdir in libucb.so wants you to include sys/dir.h, + but many SunOS 4.1.x programs included , consequently, + you're mixing native struct dirent with libucb + readdir(). The symptom of this mixup is that the first two + characters of each filename are missing. Make sure you use a + native compiler (default /opt/SUNWspro/bin/cc, which may not be in + your PATH), and not /usr/ucb/cc. + */ + + while ((entry = readdir(dirp)) != NULL) { + if (IsDirDots (entry->d_name)) + continue; + + strcpy(FullName, Path); + if (FullName[strlen(FullName)-1] != '/') + strcat(FullName, "/"); + + strcat(FullName, entry->d_name); + + if (stat(FullName, &stats) == -1) { + perror("RecursiveSend: ERROR, stat failed"); + PRINT(("RecursiveSend: FullName=%s\nentry->d_name=%s\nPath=%s\n", FullName, entry->d_name, Path)) + EXIT(("RecursiveSend: ERROR, stat() failed\n")) + } + + if (S_ISDIR(stats.st_mode)) { + ASSERT((strcmp(Path,FullName))) + PRINT(("Entering Directory %s\n", FullName)) + total_sent+= RecursiveSend (FullName); + } else { + PRINT(("Sending File %s\n", FullName)) + total_sent += SendThisFile (FullName); + } + } + closedir (dirp); + return total_sent; +} + + +#endif /* OS */ + + +int SendThisFile (char *file_path) //int fragment_len) +{ + fec_codec_info_t *codec_info; + int fragment_size; + int last_but_one_fragment_size; + int last_fragment_size; + char file_base[MAX_PATH]; + char file_name[MAX_FILENAME]; + char length[20]; + char BlockTmp4[4]; + trailer_t trailer; + struct stat file_stats; + FILE *file_to_send = NULL; + char *buf_file = NULL; + int sent = 0; + int filesize = 0; + unsigned short global_sum = 0; + unsigned short checksum = 0; + unsigned char must_swap = 0; + int nb_fragments = 0; + int ObjectLength = 0; + int CurrOffset = 0; + int fragsize = 0; + int i; + char fragment[20]; + char offset[20]; + + trailer.size = 0; + trailer.buffer = NULL; + + if(FileExist(file_path)) { + if(stat(file_path, &file_stats) == -1) { + EXIT(("Fcast: SendThisFile: Error: stat()\n")) + //PRINT(("Fcast: SendThisFile: Error: stat()\n")) + //goto end; + } + file_to_send = fopen(file_path, "rb"); + } else { + PRINT(("Fcast: SendThisFile: Error: %s, no such file!\n", file_path)) + goto end; + } + if (!(file_stats.st_mode & S_IFREG)) + EXIT(("Fcast: SendThisFile: Error: %s is not a regular file\n", + file_path)) + + codec_info = ChooseFEC((int)(file_stats.st_size)); + fragment_size = codec_info->max_fragment_size; + ASSERT(fragment_size > 0); + + if (file_stats.st_size < fragment_size) { + nb_fragments = 1; + last_but_one_fragment_size = -1; /* avoid warnings */ + } else { + nb_fragments = file_stats.st_size / fragment_size; + last_fragment_size = file_stats.st_size % fragment_size; + if (last_fragment_size > 0) + nb_fragments++; + /* + * if last fragment is less than half the fragment_size, then + * reduce size of last two fragments. + */ + if ((nb_fragments > 1) && + (last_fragment_size < (fragment_size >> 1))) { + int sz; /* size of last two fragments */ + sz = fragment_size + last_fragment_size; + last_but_one_fragment_size = sz >> 1; + last_fragment_size = sz - last_but_one_fragment_size; + } else { + last_but_one_fragment_size = fragment_size; + } + ASSERT(last_fragment_size >= 0); + ASSERT(last_but_one_fragment_size >= 0); + ASSERT(last_fragment_size <= fragment_size); + ASSERT(last_but_one_fragment_size <= fragment_size); + } + PRINT(("*** Stripping file %s into %d fragment(s)\n", + file_path, nb_fragments)) + + GetFileBaseWithoutPrefix(file_path, file_base); + + for (i = 1; i <= nb_fragments; i++) { + if (i == nb_fragments - 1) { + /* last but one fragment may be shorter... */ + fragment_size = last_but_one_fragment_size; + } + /* make room in buf_file for additional trailer and checksum */ + if (!(buf_file = (char*)malloc(fragment_size + MAX_TRAILER_SIZE))) { + EXIT(("Fcast: SendThisFile: Error: Cannot alloc memory!\n")) + } + + if ((ObjectLength = fread(buf_file, 1, fragment_size , + file_to_send)) < 0) + EXIT(("Fcast: SendThisFile: Error FcastSend: fread failed, returned %d\n", ObjectLength)) + + if (strlen(file_base)>0) { + AddMetadata(&trailer, "Content-Base", file_base); + } + + GetFileName(file_path, file_name); + AddMetadata(&trailer, "Content-Location", file_name); + + filesize = file_stats.st_size; + sprintf(length, "%d", filesize); + AddMetadata(&trailer, "Content-Filesize", length); + + fragsize = ObjectLength; + sprintf(length, "%d", fragsize); + AddMetadata(&trailer, "Content-Length", length); + + sprintf( fragment, "%d/%d", i, nb_fragments); + AddMetadata(&trailer, "Content-Fragment", fragment); + + sprintf( offset, "%d", CurrOffset); + CurrOffset += ObjectLength; + AddMetadata(&trailer, "Content-Offset", offset); + + EndTrailer(&trailer); + + if(trailer.size + 4 > MAX_TRAILER_SIZE) { + EXIT(("Fcast: SendThisFile: Error: Trailer is too big! (max=%d)\n", MAX_TRAILER_SIZE-4)) + } + /* + else PRINT(("Trailer length is %ld bytes\n",trailer.size-4)) + */ +#if 0 + if (!(buf_file = (char*)realloc(buf_file, ObjectLength + trailer.size + 4))) { + EXIT(("SendThisFile: Error: Cannot realloc memory!\n")) + } +#endif + memcpy(buf_file + ObjectLength, trailer.buffer, trailer.size); + ObjectLength+= trailer.size; + DeleteTrailer(&trailer); + + global_sum = ComputeSum((unsigned short*)buf_file, + ObjectLength, &must_swap); + checksum = ComputeChecksum(global_sum, must_swap); + + *(unsigned short*)BlockTmp4 = 0x0000; + *(unsigned short*)(BlockTmp4+2) = checksum; + + memcpy(buf_file + ObjectLength, BlockTmp4, 4); + ObjectLength += 4; + + PRINT(("Sending file %s slice %d (Data: %d Bytes - Trailer: %d Bytes)\n", file_path, i, fragsize, ObjectLength-fragsize-8)) + if (mcl_send(id, buf_file, ObjectLength) < 0) + EXIT(("Fcast: mcl_send %ld failed\n", trailer.size)) + sent+= ObjectLength; + + if(buf_file) + free(buf_file); + } + + fclose(file_to_send); +// ASSERT(sent == file_stats.st_size) + + PRINT(("File %s (%d Bytes) sent.\n\t%d fragments (objects) transfered for this file.\n\t%d Bytes transfered for this file.\n", file_path, filesize, nb_fragments, sent)) + +end: + return sent; +} + + +/* + * Updates the FEC available global variables depending on the available + * FEC codecs. + * Sets the FEC ratio for each possible FEC codec. + * Retrieves the maximum block size for each possible FEC codec. + */ +void +FindAvailableFEC (void) +{ + int codec; /* temp variable */ + int max_sz; /* temp variable */ + + ASSERT(fec_ratio >= 1.0); + /* + * NULL_FEC codec first (should always be supported) + */ + codec = MCL_FEC_SCHEME_NULL; + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&codec, sizeof(codec))) { + EXIT(("Fcast: ERROR, FEC codec NULL not available\n")) + } else { + NULL_FEC_info.available = 1; + /* + * determine the max block size, as defined by MCL, + * and the associated max file fragment size, used + * by FCAST. + */ + if (mcl_ctl(id, + MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC, + (void*)&max_sz, sizeof(max_sz))) { + EXIT(("Fcast: ERROR, mcl_ctl failed for MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC for LDGM codec\n")) + } + NULL_FEC_info.max_block_size = max_sz; + NULL_FEC_info.max_fragment_size = + min(NULL_FEC_MAX_FRAGMENT_SIZE, + max_sz - MAX_TRAILER_SIZE); + } + /* + * now let's see the other FEC codecs + */ + if (fec_ratio == 1.0) { + /* user wants no FEC */ + RSE_FEC_info.available = 0; + LDGM_STAIRCASE_FEC_info.available = 0; + LDGM_TRIANGLE_FEC_info.available = 0; + } else { + /* user wants some FEC */ + /* + * RSE + */ + codec = MCL_FEC_SCHEME_RSE_129_0; + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&codec, + sizeof(codec))) { + RSE_FEC_info.available = 0; + } else { + RSE_FEC_info.available = 1; + if (mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, + sizeof(fec_ratio))) { + EXIT(("Fcast: ERROR, mcl_ctl failed for FEC_RATIO %.3f and RSE\n", fec_ratio)) + } + /* + * determine the max block size, as defined by MCL, + * and the associated max file fragment size, used + * by FCAST. + */ + if (mcl_ctl(id, + MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC, + (void*)&max_sz, sizeof(max_sz))) { + EXIT(("Fcast: ERROR, mcl_ctl failed for MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC for RSE codec\n")) + } + RSE_FEC_info.max_block_size = max_sz; + RSE_FEC_info.max_fragment_size = + min(RSE_MAX_FRAGMENT_SIZE, + max_sz - MAX_TRAILER_SIZE); + /* tests MCL blocking algo: define a large frag size */ + //RSE_FEC_info.max_fragment_size = 512*1024; + } +#if defined(ALC) + /* + * LDGM STAIRCASE + */ + codec = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0; + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&codec, + sizeof(codec))) { + LDGM_STAIRCASE_FEC_info.available = 0; + }else { + LDGM_STAIRCASE_FEC_info.available = 1; + if (mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, + sizeof(fec_ratio))) { + EXIT(("Fcast: ERROR, mcl_ctl failed for FEC_RATIO %f for LDGM STAIRCASE codec\n", fec_ratio)) + } + /* + * determine the max block size, as defined by MCL, + * and the associated max file fragment size, used + * by FCAST. + */ + if (mcl_ctl(id, + MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC, + (void*)&max_sz, sizeof(max_sz))) { + EXIT(("Fcast: ERROR, mcl_ctl failed for MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC for LDGM STAIRCASE codec\n")) + } + LDGM_STAIRCASE_FEC_info.max_block_size = max_sz; + LDGM_STAIRCASE_FEC_info.max_fragment_size = + min(LDGM_MAX_FRAGMENT_SIZE, + max_sz - MAX_TRAILER_SIZE); + } + /* + * LDGM TRIANGLE + */ + codec = MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1; + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&codec, + sizeof(codec))) { + LDGM_TRIANGLE_FEC_info.available = 0; + }else { + LDGM_TRIANGLE_FEC_info.available = 1; + if (mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, + sizeof(fec_ratio))) { + EXIT(("Fcast: ERROR, mcl_ctl failed for FEC_RATIO %f for LDGM TRIANGLE codec\n", fec_ratio)) + } + /* + * determine the max block size, as defined by MCL, + * and the associated max file fragment size, used + * by FCAST. + */ + if (mcl_ctl(id, + MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC, + (void*)&max_sz, sizeof(max_sz))) { + EXIT(("Fcast: ERROR, mcl_ctl failed for MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC for LDGM TRIANGLE codec\n")) + } + LDGM_TRIANGLE_FEC_info.max_block_size = max_sz; + LDGM_TRIANGLE_FEC_info.max_fragment_size = + min(LDGM_MAX_FRAGMENT_SIZE, + max_sz - MAX_TRAILER_SIZE); + } +#elif defined(NORM) + LDGM_STAIRCASE_FEC_info.available = 0; + LDGM_TRIANGLE_FEC_info.available = 0; +#endif /* RM_PROTOCOL */ + // Remove following two line comment to test with RSE + //LDGM_STAIRCASE_FEC_info.available = 0; + //LDGM_TRIANGLE_FEC_info.available = 0; + if (!RSE_FEC_info.available && !LDGM_STAIRCASE_FEC_info.available && !LDGM_TRIANGLE_FEC_info.available) { + EXIT(("Fcast: ERROR, at least one of RSE or LDGM codecs must be available\n")) + } + } +} + + +/* + * Choose the most appropriate FEC codec, depending on the file size + * and the available FEC codecs. + * @param file_size file size + * @return FEC codec chosen + */ +fec_codec_info_t * +ChooseFEC (int file_size) +{ + int codec; + fec_codec_info_t *codec_info; + + if (fec_ratio == 1.0) { + ASSERT(NULL_FEC_info.available); + codec = MCL_FEC_SCHEME_NULL; + codec_info = &NULL_FEC_info; + goto codec_found; + } +#if defined(ALC) + /* + * With ALC, use LDGM first for big files and RSE for + * small files, and if the default choice is not available, + * use the other one. + */ + if (file_size >= RSE_LDGM_FILE_SIZE_THRESHOLD) { + if (fec_ratio >= 2.5 && LDGM_STAIRCASE_FEC_info.available) { + /* + * Use LDGM Staircase with large FEC expansion ratios. + */ + codec = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0; + codec_info = &LDGM_STAIRCASE_FEC_info; + } else if (LDGM_TRIANGLE_FEC_info.available) { + /* + * Use LDGM Triangle with small FEC expansion ratios. + */ + codec = MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1; + codec_info = &LDGM_TRIANGLE_FEC_info; + } else { + ASSERT(RSE_FEC_info.available) + codec = MCL_FEC_SCHEME_RSE_129_0; + codec_info = &RSE_FEC_info; + } + } else { + if (RSE_FEC_info.available) { + codec = MCL_FEC_SCHEME_RSE_129_0; + codec_info = &RSE_FEC_info; + } else { + ASSERT(LDGM_STAIRCASE_FEC_info.available) + codec = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0; + codec_info = &LDGM_STAIRCASE_FEC_info; + } + } +#elif defined(NORM) + /* With NORM, use RSE (LDGM not supported) */ + ASSERT(RSE_FEC_info.available); + codec = MCL_FEC_SCHEME_RSE_129_0; + codec_info = &RSE_FEC_info; +#endif /* RM_PROTOCOL */ + +codec_found: + /* set the codec now */ + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&codec, sizeof(codec))) { + EXIT(("Fcast: ERROR, ctl for MCL_OPT_SET_FEC_CODE (%d) failed\n", codec)) + } + return codec_info; +} + + +#if 0 +/* + * Determines the optimum file segmentation, and the appropriate FEC codec + * to use. + * @param + * @return + */ +int +FileSegmentation +{ +} +#endif diff --git a/fcast/fsend.c.org b/fcast/fsend.c.org new file mode 100644 index 0000000..3f67aea --- /dev/null +++ b/fcast/fsend.c.org @@ -0,0 +1,490 @@ +/* $Id: fsend.c,v 1.9 2004/02/04 17:15:37 roca Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * fsend.c + * + * fcast sender side functions + */ +#include "fcast.h" + +/* + * Local variables + */ +int fec_code = MCL_FEC_CODE_NULL; /* FEC code that will be used by the sender */ + /* XXX: The current version uses a single FEC code for the whole */ + /* session even if FEC can be specified on a per-object basis. */ +int max_fragment_size; /* Big files are fragmented into fragments of this + size */ + + +void FcastSend (void) +{ + int mcl_max_block_size; /* maximum size of a source block in bytes; */ + /* depends on the FEC codec used and its */ + /* limitations on the "k" parameter */ + int Bytes_sent = 0; +#if defined(ALC) + int mcl_option; +#endif /* RM_PROTOCOL */ + + + if (fec_ratio > 1.0) { +#if defined(ALC) + /* + * The user asked for FEC, so choose the codec. + * Try LDGM first, and if not applicable, revert to RSE + * NB: not supported by NORM currently... + */ +#if 0 +#else /* 0 */ /* comment #else to test with RSE */ + fec_code = MCL_FEC_CODE_LDGM; + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&fec_code, + sizeof(fec_code))) +#endif /* 0 */ +#elif defined(NORM) + /* use RSE ! */ +#endif /* RM_PROTOCOL */ + { + fec_code = MCL_FEC_CODE_RSE; + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&fec_code, + sizeof(fec_code))) { + EXIT(("Fcast: ERROR, no FEC codec available\n")) + } + } + if (mcl_ctl(id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio))) + EXIT(("Fcast: ERROR, mcl_ctl failed for FEC_RATIO\n")) + } else { + /* + * No FEC packet, so set the FEC code to NULL. + */ + fec_code = MCL_FEC_CODE_NULL; + if (mcl_ctl(id, MCL_OPT_SET_FEC_CODE, (void*)&fec_code, + sizeof(fec_code))) { + EXIT(("Fcast: ERROR, FEC codec NULL not available\n")) + } + } + /* + * Determine the maximum block size. + * This maximum is defined by the MCL library, depending on + * the FEC code in use, but it must not exceed the value + * specified in the * XXX_MAX_FRAGMENT_SIZE constant. + */ + if (mcl_ctl(id, MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC, + (void*)&mcl_max_block_size, sizeof(mcl_max_block_size))) { + EXIT(("Fcast: ERROR, mcl_ctl failed for MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC\n")) + } + /*printf("mcl_max_block_size=%d\n", mcl_max_block_size);*/ + ASSERT(mcl_max_block_size > 0); + switch (fec_code) { + case MCL_FEC_CODE_RSE: + max_fragment_size = min(RSE_MAX_FRAGMENT_SIZE, + mcl_max_block_size - MAX_TRAILER_SIZE); + /* tests the MCL blocking algorithm: define a large frag size */ + /* max_fragment_size = 512*1024; */ + break; +#if defined(ALC) + case MCL_FEC_CODE_LDGM: + max_fragment_size = min(LDPC_MAX_FRAGMENT_SIZE, + mcl_max_block_size - MAX_TRAILER_SIZE); + break; +#endif /* RM_PROTOCOL */ + default: + /* no FEC encoding... */ + max_fragment_size = min(NO_FEC_MAX_FRAGMENT_SIZE, + mcl_max_block_size - MAX_TRAILER_SIZE); + break; + } +#if defined(ALC) + /* + * NB: always use LCT1 now, in all cases... + */ + mcl_option = MCL_SCHED_LCT1; + if (mcl_ctl(id, MCL_OPT_SCHED, (void*)&mcl_option, sizeof(mcl_option))) { + EXIT(("Fcast: mcl_ctl MCL_OPT_SCHED failed for LCT1\n")) + } +#if 0 + if (tx_huge_file > 0) + mcl_option = MCL_SCHED_LCT3; + else + mcl_option = MCL_SCHED_LCT2; + if (single_layer == 0) { + /* + * set the scheduling mode, except for single layer where + * LCT1 is required + */ + if (mcl_ctl(id, MCL_OPT_SCHED, (void*)&mcl_option, + sizeof(mcl_option))) + EXIT(("Fcast: mcl_ctl MCL_OPT_SCHED failed\n")) + } +#endif + if (optimode == OPTIMIZE_SPACE) + { + mcl_option = MCL_SCHED_PARTIALLY_MIXED_ORDER; + if (mcl_ctl(id, MCL_OPT_OBJ_SCHED, (void*)&mcl_option, + sizeof(mcl_option))) + EXIT(("Fcast: mcl_ctl MCL_OPT_SCHED failed\n")) + } + else if (optimode == OPTIMIZE_SPEED) + { + mcl_option = MCL_SCHED_MIXED_ORDER; + if (mcl_ctl(id, MCL_OPT_OBJ_SCHED, (void*)&mcl_option, sizeof(mcl_option))) + EXIT(("Fcast: mcl_ctl MCL_OPT_OBJ_SCHED failed\n")) + } + else if (optimode == OPTIMIZE_CPU) + { + mcl_option = MCL_SCHED_MIXED_ORDER; + if (mcl_ctl(id, MCL_OPT_OBJ_SCHED, (void*)&mcl_option, sizeof(mcl_option))) + EXIT(("Fcast: mcl_ctl MCL_OPT_OBJ_SCHED failed\n")) + } + else + { + EXIT(("Fcast: ERROR, invalid optimization mode!")) + } +#elif defined(NORM) + /* no equivalent */ +#endif /* RM_PROTOCOL */ + +/* + mcl_option = 1; + mcl_ctl(id, MCL_OPT_REUSE_APPLI_TX_BUFFER, (void*)&mcl_option, sizeof(mcl_option)); +*/ + + if (recursive) { +#if defined(ALC) + if(mcl_ctl(id, MCL_OPT_KEEP_DATA, NULL, 0)) + EXIT(("Fcast: mcl_ctl KEEP_DATA failed\n")) +#endif /* RM_PROTOCOL */ + Bytes_sent = RecursiveSend(fileparam); +#if defined(ALC) + if(mcl_ctl(id, MCL_OPT_PUSH_DATA, NULL, 0)) + EXIT(("Fcast: mcl_ctl PUSH_DATA failed\n")) +#endif /* RM_PROTOCOL */ + } + else + { +#if defined(ALC) + if(mcl_ctl(id, MCL_OPT_KEEP_DATA, NULL, 0)) + EXIT(("Fcast: mcl_ctl KEEP_DATA returned an error\n")) +#endif /* RM_PROTOCOL */ + Bytes_sent = SendThisFile(fileparam, max_fragment_size); +#if defined(ALC) + if(mcl_ctl(id, MCL_OPT_PUSH_DATA, NULL, 0)) + EXIT(("Fcast: mcl_ctl PUSH_DATA returned an error\n")) +#endif /* RM_PROTOCOL */ + } + + mcl_close(id); + PRINT(("\nFcastSend complete. %d bytes sent\n", Bytes_sent)) +} + + + +#ifdef WIN32 + +int RecursiveSend (char* Path) +{ + + HANDLE dirp = NULL; + WIN32_FIND_DATA entry; + + unsigned int total_sent = 0; + char FullName[MAX_PATH + MAX_FILENAME]; + char FindString[MAX_PATH]; + strcpy(FindString, Path); + strcat(FindString, "\\*"); + + dirp = FindFirstFile(FindString, &entry); + + if (dirp == INVALID_HANDLE_VALUE) + { + EXIT(("Fcast: ERROR, in recursive mode, the given parameter MUST BE a valid directory name\nAborting...\n")) + } + + if (!IsDirDots (entry.cFileName)) + { + strcpy(FullName, Path); + if(FullName[strlen(FullName)-1] == '\\') + FullName[strlen(FullName)-1] = '/'; + + if(FullName[strlen(FullName)-1] != '/') + strcat(FullName,"/"); + + strcat(FullName, entry.cFileName); + + if( entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + ASSERT((strcmp(Path,FullName))) + PRINT(("Entering Directory %s\n", FullName)) + total_sent+= RecursiveSend (FullName); + } + else + { + PRINT(("\nSending File %s\n", FullName)) + total_sent += SendThisFile (FullName, max_fragment_size); + } + } + + while ( FindNextFile(dirp, &entry) ) + { + if (IsDirDots (entry.cFileName)) + continue; + + strcpy(FullName, Path); + if(FullName[strlen(FullName)-1] == '\\') + FullName[strlen(FullName)-1] = '/'; + + if(FullName[strlen(FullName)-1] != '/') + strcat(FullName,"/"); + + strcat(FullName, entry.cFileName); + + if( entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + ASSERT((strcmp(Path,FullName))) + PRINT(("Entering Directory %s\n", FullName)) + total_sent+= RecursiveSend (FullName); + } + else + { + PRINT(("\nSending File %s\n", FullName)) + total_sent += SendThisFile (FullName, max_fragment_size); + } + } + FindClose(dirp); + return total_sent; +} + + +#else + +int RecursiveSend (char* Path) +{ + unsigned int total_sent = 0; + struct dirent *entry; + struct stat stats; + char FullName[MAX_PATH + MAX_FILENAME]; + DIR *dirp; + + if ((dirp = opendir (Path)) == NULL) + { + perror(Path); + EXIT(("RecursiveSend: ERROR, opendir failed\n")) + } + +/* +For SOLARIS users: +Why doesn't readdir work? It chops the first two characters of +all filenames. + +You're probably linking with libucb and didn't read question +6.18. (Readdir in libucb.so wants you to include sys/dir.h, +but many SunOS 4.1.x programs included , consequently, +you're mixing native struct dirent with libucb +readdir(). The symptom of this mixup is that the first two +characters of each filename are missing. Make sure you use a +native compiler (default /opt/SUNWspro/bin/cc, which may not be in +your PATH), and not /usr/ucb/cc. +*/ + + while ((entry = readdir(dirp)) != NULL) + { + if (IsDirDots (entry->d_name)) + continue; + + strcpy(FullName, Path); + if (FullName[strlen(FullName)-1] != '/') + strcat(FullName, "/"); + + strcat(FullName, entry->d_name); + + if (stat(FullName, &stats) == -1) + { + perror("RecursiveSend: ERROR, stat failed"); + PRINT(("RecursiveSend: FullName=%s\nentry->d_name=%s\nPath=%s\n", FullName, entry->d_name, Path)) + EXIT(("RecursiveSend: ERROR, stat() failed\n")) + } + + if (S_ISDIR(stats.st_mode)) + { + ASSERT((strcmp(Path,FullName))) + PRINT(("Entering Directory %s\n", FullName)) + total_sent+= RecursiveSend (FullName); + } + else + { + PRINT(("Sending File %s\n", FullName)) + total_sent += SendThisFile (FullName, max_fragment_size); + } + } + closedir (dirp); + return total_sent; +} + +#endif + + + +int SendThisFile (char *file_path, int fragment_len) +{ + char file_base[MAX_PATH]; + char file_name[MAX_FILENAME]; + char length[20]; + char BlockTmp4[4]; + trailer_t trailer; + struct stat file_stats; + FILE *file_to_send = NULL; + char *buf_file = NULL; + int sent = 0; + int filesize = 0; + unsigned short global_sum = 0; + unsigned short checksum = 0; + unsigned char must_swap = 0; + + int nb_fragments = 0; + int ObjectLength = 0; + int CurrOffset = 0; + int fragsize = 0; + int i; + char fragment[20]; + char offset[20]; + + + trailer.size = 0; + trailer.buffer = NULL; + +// if(mcl_ctl(id, MCL_OPT_KEEP_DATA, NULL, 0)) +// EXIT(("fcast: mcl_ctl returned an error\n")) + + if(FileExist(file_path)) + { if(stat(file_path, &file_stats) == -1) + { PRINT(("Error: stat()\n")) + goto end; + } + file_to_send = fopen(file_path, "rb"); + } + else + { PRINT(("Error: %s, no such file!\n", file_path)) + goto end; + } + if( !(file_stats.st_mode & S_IFREG) ) + EXIT(("Error: %s is not a regular file\n", file_path)) + + ASSERT(fragment_len > 0); + + if(file_stats.st_size < fragment_len ) + { + nb_fragments = 1; + } + else + { + nb_fragments = file_stats.st_size / fragment_len; + if (file_stats.st_size % fragment_len) + { + nb_fragments++; + } + } + PRINT(("*** Stripping file %s into %d fragment(s)\n", file_path, nb_fragments)) + + GetFileBaseWithoutPrefix(file_path, file_base); + + for( i=1; i<=nb_fragments; i++) + { + if(!(buf_file = (char*)malloc(fragment_len))) { + EXIT(("Error: Cannot alloc memory!\n")) + } + + if( (ObjectLength = fread(buf_file, 1, fragment_len , file_to_send)) < 0) + EXIT(("Error FcastSend: fread failed, returned %d\n", ObjectLength)) + + if(strlen(file_base)>0) + { + AddMetadata(&trailer, "Content-Base", file_base); + } + + GetFileName(file_path, file_name); + AddMetadata(&trailer, "Content-Location", file_name); + + filesize = file_stats.st_size; + sprintf(length, "%d", filesize); + AddMetadata(&trailer, "Content-Filesize", length); + + fragsize = ObjectLength; + sprintf(length, "%d", fragsize); + AddMetadata(&trailer, "Content-Length", length); + + sprintf( fragment, "%d/%d", i, nb_fragments); + AddMetadata(&trailer, "Content-Fragment", fragment); + + sprintf( offset, "%d", CurrOffset); + CurrOffset += ObjectLength; + AddMetadata(&trailer, "Content-Offset", offset); + + EndTrailer(&trailer); + + if(trailer.size + 4 > MAX_TRAILER_SIZE) { + EXIT(("Error: Trailer is too big! (max=%d)\n", MAX_TRAILER_SIZE-4)) + } +/* + else + PRINT(("Trailer length is %ld bytes\n",trailer.size-4)) +*/ + + if (!(buf_file = (char*)realloc(buf_file, ObjectLength + trailer.size))) { + EXIT(("Error: Cannot realloc memory!\n")) + } + memcpy( buf_file + ObjectLength, trailer.buffer, trailer.size); + ObjectLength+= trailer.size; + DeleteTrailer(&trailer); + + global_sum = ComputeSum( (unsigned short*)buf_file, ObjectLength, &must_swap ); + checksum = ComputeChecksum(global_sum, must_swap); + + *(unsigned short*)BlockTmp4 = 0x0000; + *(unsigned short*)(BlockTmp4+2) = checksum; + + if (!(buf_file = (char*)realloc(buf_file, ObjectLength + 4))) { + EXIT(("Error: Cannot realloc memory!\n")) } + memcpy( buf_file + ObjectLength, BlockTmp4, 4); + ObjectLength += 4; + + PRINT(("Sending file %s slice %d (Data: %d Bytes - Trailer: %d Bytes)\n", file_path, i, fragsize, ObjectLength-fragsize-8)) + if (mcl_send(id, buf_file, ObjectLength) < 0) + EXIT((": mcl_send %ld failed\n", trailer.size)) + sent+= ObjectLength; + + if(buf_file) free(buf_file); + } + + fclose(file_to_send); +// ASSERT(sent == file_stats.st_size) + + PRINT(("File %s (%d Bytes) sent.\n\t%d fragments (objects) transfered for this file.\n\t%d Bytes transfered for this file.\n", file_path, filesize, nb_fragments, sent)) + +end: + +// if(mcl_ctl(id, MCL_OPT_PUSH_DATA, NULL, 0)) +// EXIT(("fcast: mcl_ctl returned an error\n")) + + return sent; +} + diff --git a/fcast/fsend.h b/fcast/fsend.h new file mode 100644 index 0000000..8cffc3e --- /dev/null +++ b/fcast/fsend.h @@ -0,0 +1,36 @@ +/* $Id: fsend.h,v 1.2 2004/02/09 11:29:53 roca Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * fsend.h + * + * fcast sender side functions headers + */ + + +extern void FcastSend (void); +extern int SendThisFile (char*); +extern int RecursiveSend (char*); +extern void FindAvailableFEC (void); +extern struct fec_codec_info *ChooseFEC (int); + + diff --git a/fcast/getopt.c b/fcast/getopt.c new file mode 100644 index 0000000..48f7618 --- /dev/null +++ b/fcast/getopt.c @@ -0,0 +1,146 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// FILE: getopt.c +// +// GetOption function +// +// FUNCTIONS: +// +// GetOption() - Get next command line option and parameter +// +// COMMENTS: +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "getopt.h" + +/////////////////////////////////////////////////////////////////////////////// +// +// FUNCTION: GetOption() +// +// Get next command line option and parameter +// +// PARAMETERS: +// +// argc - count of command line arguments +// argv - array of command line argument strings +// pszValidOpts - string of valid, case-sensitive option characters, +// a colon ':' following a given character means that +// option can take a parameter +// ppszParam - pointer to a pointer to a string for output +// +// RETURNS: +// +// If valid option is found, the character value of that option +// is returned, and *ppszParam points to the parameter if given, +// or is NULL if no param +// If standalone parameter (with no option) is found, 1 is returned, +// and *ppszParam points to the standalone parameter +// If option is found, but it is not in the list of valid options, +// -1 is returned, and *ppszParam points to the invalid argument +// When end of argument list is reached, 0 is returned, and +// *ppszParam is NULL +// +// COMMENTS: +// +/////////////////////////////////////////////////////////////////////////////// + +int GetOption ( + int argc, + char** argv, + char* pszValidOpts, + char** ppszParam) +{ + static int iArg = 1; + char chOpt; + char* psz = NULL; + char* pszParam = NULL; + + if (iArg < argc) + { + psz = &(argv[iArg][0]); + if (*psz == '-' || *psz == '/') + { + // we have an option specifier + chOpt = argv[iArg][1]; + if (isalnum(chOpt) || ispunct(chOpt)) + { + // we have an option character + psz = strchr(pszValidOpts, chOpt); + if (psz != NULL) + { + // option is valid, we want to return chOpt + if (psz[1] == ':') + { + // option can have a parameter + psz = &(argv[iArg][2]); + if (*psz == '\0') + { + // must look at next argv for param + if (iArg+1 < argc) + { + psz = &(argv[iArg+1][0]); + if (*psz == '-' || *psz == '/') + { + // next argv is a new option, so param + // not given for current option + } + else + { + // next argv is the param + iArg++; + pszParam = psz; + } + } + else + { + // reached end of args looking for param + } + + } + else + { + // param is attached to option + pszParam = psz; + } + } + else + { + // option is alone, has no parameter + } + } + else + { + // option specified is not in list of valid options + chOpt = -1; + pszParam = &(argv[iArg][0]); + } + } + else + { + // though option specifier was given, option character + // is not alpha or was was not specified + chOpt = -1; + pszParam = &(argv[iArg][0]); + } + } + else + { + // standalone arg given with no option specifier + chOpt = 1; + pszParam = &(argv[iArg][0]); + } + } + else + { + // end of argument list + chOpt = 0; + } + + iArg++; + *ppszParam = pszParam; + return (chOpt); +} diff --git a/fcast/getopt.h b/fcast/getopt.h new file mode 100644 index 0000000..3dc78f9 --- /dev/null +++ b/fcast/getopt.h @@ -0,0 +1,12 @@ +/////////////////////////////////////////////////////////////////////////////// +// +// FILE: getopt.h +// +// Header for the GetOption function +// +// COMMENTS: +// +/////////////////////////////////////////////////////////////////////////////// + +// function prototypes +int GetOption (int argc, char** argv, char* pszValidOpts, char** ppszParam); diff --git a/fcast/macros.h b/fcast/macros.h new file mode 100644 index 0000000..f62d996 --- /dev/null +++ b/fcast/macros.h @@ -0,0 +1,67 @@ +/* $Id: macros.h,v 1.1.1.1 2003/09/03 12:45:42 chneuman Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#ifndef MACROS_H +#define MACROS_H + +#include + + +/****** general macros ******/ + +#ifndef min +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#endif +#ifndef max +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#endif + +/* + * print to stdout + */ +#define PRINT(a) { if(!silent) { printf a; fflush(stdout); } } + +/* + * print and exit + */ +#define EXIT(a) { if(!silent) { printf a; fflush(stdout); } exit(-1); } + +/* + * test, print and exit if error (i.e. if != 0) + */ +#define EXIT_ON_ERROR(err, a) { if (err) { EXIT(a) } } + + +#define ASSERT(c) { \ + if (!(c)) { \ + fprintf(stderr, "ASSERT [%s:%d] failed\n", \ + __FILE__, __LINE__); \ + fflush(stderr); \ + exit (-1); \ + } \ + } + +#define BUFFER_TO_INT32(x) ((*(x)<<24) + (*(x+1)<<16) + (*(x+2)<<8) + (*(x+3))) + + +#endif diff --git a/fcast/metadata.c b/fcast/metadata.c new file mode 100644 index 0000000..746993a --- /dev/null +++ b/fcast/metadata.c @@ -0,0 +1,312 @@ +/* $Id: metadata.c,v 1.1.1.1 2003/09/03 12:45:42 chneuman Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * metadata.c + * + * Compute Metadata infos for fcast trailers. + */ +#include "fcast.h" +#include + +void AddMetadata(trailer_t *trailer, char *MetaName, char* MetaContent) +{ unsigned int MetaLen; + + MetaLen = strlen(MetaName) + strlen(MetaContent) + 3; + if (!(trailer->buffer = (char*)realloc(trailer->buffer, trailer->size + MetaLen))) + { + EXIT(("Error: Cannot alloc memory!\n")) + } + + memcpy( trailer->buffer + trailer->size, MetaName, strlen(MetaName)); + trailer->size += strlen(MetaName); + *(trailer->buffer+trailer->size) = ':'; + trailer->size ++; + memcpy( trailer->buffer + trailer->size, MetaContent, strlen(MetaContent)); + trailer->size += strlen(MetaContent); + *(trailer->buffer + trailer->size) = '\r'; + trailer->size ++; + *(trailer->buffer + trailer->size) = '\n'; + trailer->size ++; +} + + +void EndTrailer(trailer_t *trailer) +{ int final_size = 0; + + if (!(trailer->buffer = (char*)realloc(trailer->buffer, trailer->size + 4) )) + { + EXIT(("Error: Cannot alloc memory!\n")) + + } + final_size = trailer->size; /* do not count the size field itself */ + + *(trailer->buffer + trailer->size) = (final_size & 0xFF000000) >> 24; + trailer->size++; + *(trailer->buffer + trailer->size) = (final_size & 0x00FF0000) >> 16; + trailer->size++; + *(trailer->buffer + trailer->size) = (final_size & 0x0000FF00) >> 8; + trailer->size++; + *(trailer->buffer + trailer->size) = (final_size & 0x0000FF); + trailer->size++; +} + +void DeleteTrailer(trailer_t *trailer) +{ + free(trailer->buffer); + trailer->size = 0; + trailer->buffer = NULL; + +} + + +void AddMetaToList(meta_t **MetaList, meta_t NewMeta) +{ + if (*MetaList == NULL) { + if (!(*MetaList = (meta_t *)malloc(sizeof(meta_t)))) { + EXIT(("Error: Cannot alloc memory!\n")) + } + strncpy((*MetaList)->name, NewMeta.name,MAX_NAMELEN ); + strncpy((*MetaList)->content, NewMeta.content,MAX_CONTLEN ); + (*MetaList)->value = NewMeta.value; + (*MetaList)->next = NULL; + } + else { + meta_t *List = *MetaList; + while (List->next != NULL) { + List = List->next; + } + if (!(List->next = (meta_t *)malloc(sizeof(meta_t)))) { + EXIT(("Error: Cannot alloc memory!\n")) + } + List = List->next; + strcpy(List->name, NewMeta.name); + strcpy(List->content, NewMeta.content); + List->value = NewMeta.value; + List->next = NULL; + } +} + + +meta_t* ParseTrailer(char *TrailerBuff) +{ + meta_t *MetaList = NULL; + meta_t NewMeta; + char *name, *content; + + name = strtok( TrailerBuff, ":" ); + + while( name != NULL ) /* while there are Metadatas in the buffer */ + { + strncpy(NewMeta.name , name, MAX_NAMELEN); + content = strtok( NULL, "\n" ); + if(content == NULL) { + printf("Invalid Trailer!\n"); + goto failed; + } + if(content[strlen(content)-1] == '\r') + content[strlen(content)-1] = '\0'; + + strncpy(NewMeta.content , content, MAX_CONTLEN); + + if (isdigit((int)*content)) + NewMeta.value = atol(content); + else + NewMeta.value = 0; + + AddMetaToList( &MetaList, NewMeta); + name = strtok( NULL, ":" ); + } + + return MetaList; + +failed: return NULL; + +} + +meta_t* FindMeta(meta_t *MetaList, char *MetaName) +{ + meta_t *found = NULL; + meta_t *listloop = MetaList; + + while(listloop != NULL) + { + if( !strcmp(listloop->name, MetaName) ) { + found = listloop; + break; + } + listloop = listloop->next; + } + return found; +} + + + +void DestroyMetalist(meta_t *MetaList) +{ + meta_t *looplist = MetaList; + meta_t *toDelete; + + while (looplist != NULL) + { + toDelete = looplist; + looplist = looplist->next; + free(toDelete); + } + +} + + +void PrintMetaList(meta_t *MetaList) +{ + meta_t *lpMetaData = MetaList; + while(lpMetaData != NULL) + { + PRINT(("\t%s: %s\n", lpMetaData->name, lpMetaData->content)) + lpMetaData = lpMetaData->next; + } +} + + +void GetFilePathFromMeta (meta_t *MetaList, char *FullFilePath) +{ + char file_base[MAX_PATH]; + char file_name[MAX_FILENAME]; + meta_t *lpMetaData = NULL; + + memset((void *)file_base, 0, MAX_PATH); + memset((void *)file_name, 0, MAX_FILENAME); + + lpMetaData = FindMeta(MetaList, "Content-Location"); + if(lpMetaData == NULL) + { + EXIT(("Meta Content-location unavailable, file name is unknown, can't save...\n")) + } + strncpy(file_name, lpMetaData->content, strlen(lpMetaData->content)); + if((lpMetaData = FindMeta(MetaList, "Content-Base"))!=NULL ) + { + char filebasetmp[MAX_PATH]; + ASSERT(strlen(lpMetaData->content)>1); + memset((void *)filebasetmp, 0, MAX_PATH); + + strncpy(filebasetmp, lpMetaData->content, strlen(lpMetaData->content)); + filebasetmp[strlen(lpMetaData->content)] = 0; + + if( filebasetmp[0] != '.' ) + { + if( filebasetmp[0] != '/' && filebasetmp[0] != '\\' && filebasetmp[1] != ':') + { +#ifdef WIN32 + strcpy(file_base, ".\\"); +#else + strcpy(file_base, "./"); +#endif + } + + else + { + strcpy(file_base, "./"); + } + } + if(filebasetmp[1] == ':') + { + strcat(file_base, (filebasetmp+2)); + } + else + { + strcat(file_base, filebasetmp); + } + } + else + { +#ifdef WIN32 + strcpy(file_base, ".\\\0"); +#else + strcpy(file_base, "./\0"); +#endif + } + + memset((void*)FullFilePath, 0, MAX_FILENAME + MAX_PATH); + strcpy(FullFilePath, file_base); + strcat(FullFilePath, file_name); +} + + +long GetMetaLength(meta_t *MetaList) +{ + meta_t *lpMetaData = FindMeta(MetaList, "Content-Length"); + if(lpMetaData == NULL) + { + EXIT(("Error: Missing Meta Content-Length")) + } + return lpMetaData->value; +} + + +long GetMetaFilesize(meta_t *MetaList) +{ + meta_t *lpMetaData = FindMeta(MetaList, "Content-Filesize"); + if(lpMetaData == NULL) + { + EXIT(("Error: Missing Meta Content-Filesize")) + } + return lpMetaData->value; +} + + +int GetMetaFragment(meta_t *MetaList, int *FragIndice, int *NbFragTot) +{ + meta_t *lpMetaData = FindMeta(MetaList, "Content-Fragment"); + if(lpMetaData == NULL) + { + EXIT(("Error: Meta Content-Fragment unavailable\n")) + } + else + { char *token; + token = strtok( lpMetaData->content, "/" ); + if( token != NULL ) + { + *FragIndice = atoi(token); + token = strtok( NULL, "/" ); + if( token != NULL ) + *NbFragTot = atoi(token); + else + EXIT(("Error: Invalide Meta (Content-Fragment)\n")) + } + else + EXIT(("Error: Invalid Meta (Content-Fragment)\n")) + } + return *NbFragTot; +} + + +long GetMetaOffset(meta_t *MetaList) +{ + meta_t *lpMetaData = FindMeta(MetaList, "Content-Offset"); + if(lpMetaData == NULL) + { + EXIT(("Error: Missing Meta Content-Offset")) + } + return lpMetaData->value; +} + diff --git a/fcast/metadata.h b/fcast/metadata.h new file mode 100644 index 0000000..9170997 --- /dev/null +++ b/fcast/metadata.h @@ -0,0 +1,67 @@ +/* $Id: metadata.h,v 1.1.1.1 2003/09/03 12:45:42 chneuman Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include +#include +#include +#include + +#include "macros.h" + +#define MAX_NAMELEN 128 +#define MAX_CONTLEN 256 + + +typedef struct trailer_struct +{ + unsigned long size; + char * buffer; +}trailer_t; + + +typedef struct meta_struct +{ + char name[MAX_NAMELEN]; /* The meta name */ + char content[MAX_CONTLEN]; /* The meta content */ + long value; /* The meta content value if it's a number */ + struct meta_struct *next; /* the next meta in the trailer, or NULL */ +}meta_t; + + +void AddMetadata(trailer_t *trailer, char *MetaName, char *MetaContent); +void EndTrailer(trailer_t *trailer); +void DeleteTrailer(trailer_t *trailer); + + +meta_t* ParseTrailer(char *TrailerBuff); + /* warning: TrailerBuff is modified by ParseTrailer */ +meta_t* FindMeta(meta_t *MetaList, char *MetaName); +void DestroyMetalist(meta_t *MetaList); +void PrintMetaList(meta_t *MetaList); + +void GetFilePathFromMeta(meta_t *MetaList, char *FullFilePath); +long GetMetaLength(meta_t *MetaList); +long GetMetaFilesize(meta_t *MetaList); +long GetMetaOffset(meta_t *MetaList); +int GetMetaFragment(meta_t *MetaList, int *FragIndice, int *NbFragTot); + diff --git a/fcast/testsum.c b/fcast/testsum.c new file mode 100644 index 0000000..0e494cb --- /dev/null +++ b/fcast/testsum.c @@ -0,0 +1,145 @@ +/* $Id: testsum.c,v 1.1.1.1 2003/09/03 12:45:42 chneuman Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * Test program for checksum generations + */ +#include +#include +#include "checksum.h" + + + int main(int argc, char *argv[]) + { + unsigned int i = 0; + unsigned char *block1 = NULL; + unsigned char *block2 = NULL; + unsigned char *block3 = NULL; + unsigned short not_checksum = 0; + unsigned short checksum = 0; + char must_swap = 0; + unsigned int size = 0; + unsigned char abyte = 0; + int strip = 0; + unsigned int read = 0; + + + printf("\nTestSum v1.0b (c)J. LABOURE, 2ooo\n=> Compute and test an Internet Checksum\n\n"); + + read1: printf("Number of bytes? "); + fflush(stdin); + scanf("%d", &size); + if( size < 1 ) + { + printf("Error: invalid number!\n"); + goto read1; + } + + printf("Strip at: "); + fflush(stdin); + scanf("%d", &strip); + if(strip<=0 || strip > (int)size) + { + printf("No striping...\n"); + if (!(block1 = (char *)malloc(size))) + { + printf("Error: Cannot alloc memory!\n"); + return -1; + } + + for( i=0; i< size; i++ ) + { + read2: printf("Content for byte %d: ", i+1); + fflush(stdin); + scanf("%X", &read); + if( read> 0xFF ) + { + printf("Error: invalid byte value!\n"); + goto read2; + } + abyte = (unsigned char) read; + printf(" Read 0x%X\n", abyte); + + *(block1+i) = abyte; + } + + not_checksum = ComputeSum( (unsigned short*)block1, size, NULL ); + checksum = ~not_checksum; + if (checksum == 0) + printf("Checksum OK\n"); + printf("Checksum %d\n", checksum); + } + else + { + if ( !( block1 = (char *)malloc(strip) ) || !( block2 = (char *)malloc(size-strip) ) || !( block3 = (char *)malloc(4) ) ) + { + printf("Error: Cannot alloc memory!\n"); + return -1; + } + + for( i=0; i< strip; i++ ) + { + read22: printf("Content for byte %d: ", i+1); + fflush(stdin); + scanf("%X", &read); + if( read> 0xFF ) + { + printf("Error: invalid byte value!\n"); + goto read22; + } + abyte = (unsigned char) read; + printf(" Read 0x%X\n", abyte); + + *(block1+i) = abyte; + } + printf("--- Stripping Here! ---\n"); + + for( i=strip; i< size; i++ ) + { + read222: printf("Content for byte %d: ", i+1); + fflush(stdin); + scanf("%X", &read); + if( read> 0xFF ) + { + printf("Error: invalid byte value!\n"); + goto read222; + } + abyte = (unsigned char) read; + printf(" Read 0x%X\n", abyte); + + *(block2+i-strip) = abyte; + } + + + * (unsigned short*)block3 = ComputeSum( (unsigned short*)block1, strip , &must_swap); + * (unsigned short*)(block3+2) = ComputeSum( (unsigned short*)block2, size-strip , &must_swap); + + not_checksum = ComputeSum( (unsigned short*)block3, 4, NULL ); + checksum = ~not_checksum; + if (checksum == 0) + printf("Checksum OK\n"); + printf("\nDone! Global Sum=0x%X, Checksum=0x%X\n", not_checksum, checksum); + + } + + return 1; +} diff --git a/fcastwin/FcastAboutDlg.cpp b/fcastwin/FcastAboutDlg.cpp new file mode 100644 index 0000000..e8e70c7 --- /dev/null +++ b/fcastwin/FcastAboutDlg.cpp @@ -0,0 +1,31 @@ +#include "stdafx.h" +#include "FcastWin.h" +#include "FcastWinDlg.h" +#include "FcastAboutDlg.h" +#include "afxwin.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) +END_MESSAGE_MAP() + + +CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) +{ +} + +void CAboutDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_EDIT_CREDITS, m_Credits); +} + +BOOL CAboutDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + m_Credits.SetWindowText("MCL comes with ABSOLUTELY NO WARRANTY; This is free software,\r\nand you are welcome to redistribute it under certain conditions;\r\nSee the GNU General Public License as published by the Free Software\r\nFoundation, version 2 or later, for more details.\r\n\r\nCredits:\r\n * Vincent Roca (since Oct 2000: INRIA R.A., before: Univ. Paris 6)\r\n * Julien Laboure (since May 2000: INRIA R.A.)\r\n * Benoit Mordelet (since December 2000: Activia Networks)\r\n * fec.c -- forward error corection based on Vandermonde matrices\r\n (C)1997-98 Luigi Rizzo (luigi@iet.unipi.it) (980624)\r\n Portions derived from code by Phil Karn (karn@ka9q.ampr.org),\r\n Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and\r\n Hari Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995"); + return TRUE; // return TRUE unless you set the focus to a control + // EXCEPTION: OCX Property Pages should return FALSE +} \ No newline at end of file diff --git a/fcastwin/FcastAboutDlg.h b/fcastwin/FcastAboutDlg.h new file mode 100644 index 0000000..c423581 --- /dev/null +++ b/fcastwin/FcastAboutDlg.h @@ -0,0 +1,21 @@ + + +// boîte de dialogue CAboutDlg utilisée pour la boîte de dialogue 'À propos de' pour votre application +class CAboutDlg : public CDialog +{ +public: + CAboutDlg(); + +// Données de la boîte de dialogue + enum { IDD = IDD_ABOUTBOX }; + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // prise en charge de DDX/DDV + +// Implémentation +protected: + DECLARE_MESSAGE_MAP() +public: + virtual BOOL OnInitDialog(); + CEdit m_Credits; +}; diff --git a/fcastwin/FcastWin.aps b/fcastwin/FcastWin.aps new file mode 100644 index 0000000..288793b Binary files /dev/null and b/fcastwin/FcastWin.aps differ diff --git a/fcastwin/FcastWin.cpp b/fcastwin/FcastWin.cpp new file mode 100644 index 0000000..77a4546 --- /dev/null +++ b/fcastwin/FcastWin.cpp @@ -0,0 +1,72 @@ +// FcastWin.cpp : Définit les comportements de classe pour l'application. +// + +#include "stdafx.h" +#include "FcastWin.h" +#include "FcastWinDlg.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + +// CFcastWinApp + +BEGIN_MESSAGE_MAP(CFcastWinApp, CWinApp) + ON_COMMAND(ID_HELP, CWinApp::OnHelp) +END_MESSAGE_MAP() + + +// construction de CFcastWinApp + +CFcastWinApp::CFcastWinApp() +{ + // TODO : ajoutez ici le code de la construction. + // Placez toutes les initialisations dans InitInstance +} + + +// Le seul et unique objet CFcastWinApp + +CFcastWinApp theApp; + + +// initialisation de CFcastWinApp + +BOOL CFcastWinApp::InitInstance() +{ + // InitCommonControls() est requis sur Windows XP si le manifeste de l'application + // spécifie l'utilisation de ComCtl32.dll version 6 ou ultérieure pour activer les + // styles visuels. Dans le cas contraire, la création de fenêtres échouera. + InitCommonControls(); + + CWinApp::InitInstance(); + + AfxEnableControlContainer(); + AfxInitRichEdit2(); + CoInitialize(NULL); + + + CFcastWinDlg dlg; + m_pMainWnd = &dlg; + INT_PTR nResponse = dlg.DoModal(); + if (nResponse == IDOK) + { + // TODO : Placez ici le code définissant le comportement lorsque la boîte de dialogue est + // fermée avec OK + } + else if (nResponse == IDCANCEL) + { + // TODO : Placez ici le code définissant le comportement lorsque la boîte de dialogue est + // fermée avec Annuler + } + + dlg.DestroyWindow(); + + CoUninitialize(); + + + // Lorsque la boîte de dialogue est fermée, retourner FALSE afin de quitter + // l'application, plutôt que de démarrer la pompe de messages de l'application. + return FALSE; +} diff --git a/fcastwin/FcastWin.h b/fcastwin/FcastWin.h new file mode 100644 index 0000000..d497333 --- /dev/null +++ b/fcastwin/FcastWin.h @@ -0,0 +1,31 @@ +// FcastWin.h : fichier d'en-tête principal pour l'application PROJECT_NAME +// + +#pragma once + +#ifndef __AFXWIN_H__ + #error include 'stdafx.h' before including this file for PCH +#endif + +#include "res/resource.h" // symboles principaux + + +// CFcastWinApp : +// Consultez FcastWin.cpp pour l'implémentation de cette classe +// + +class CFcastWinApp : public CWinApp +{ +public: + CFcastWinApp(); + +// Substitutions + public: + virtual BOOL InitInstance(); + +// Implémentation + + DECLARE_MESSAGE_MAP() +}; + +extern CFcastWinApp theApp; diff --git a/fcastwin/FcastWin.sln b/fcastwin/FcastWin.sln new file mode 100644 index 0000000..3b2d258 --- /dev/null +++ b/fcastwin/FcastWin.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 7.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FcastWin", "FcastWin.vcproj", "{6631EBB7-243F-4ED1-ADD4-AC41E65D8B26}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {6631EBB7-243F-4ED1-ADD4-AC41E65D8B26}.Debug.ActiveCfg = Release|Win32 + {6631EBB7-243F-4ED1-ADD4-AC41E65D8B26}.Debug.Build.0 = Release|Win32 + {6631EBB7-243F-4ED1-ADD4-AC41E65D8B26}.Release.ActiveCfg = Release|Win32 + {6631EBB7-243F-4ED1-ADD4-AC41E65D8B26}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/fcastwin/FcastWin.vcproj b/fcastwin/FcastWin.vcproj new file mode 100644 index 0000000..c92efd3 --- /dev/null +++ b/fcastwin/FcastWin.vcproj @@ -0,0 +1,186 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/fcastwin/FcastWinDlg.cpp b/fcastwin/FcastWinDlg.cpp new file mode 100644 index 0000000..501a91b --- /dev/null +++ b/fcastwin/FcastWinDlg.cpp @@ -0,0 +1,1035 @@ +// FcastWinDlg.cpp : fichier d'implémentation +// + +#include "stdafx.h" +#include "FcastWin.h" +#include "FcastWinDlg.h" +#include "FcastAboutDlg.h" +#include "afxwin.h" +#include + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + + + +// boîte de dialogue CFcastWinDlg +CFcastWinDlg::CFcastWinDlg(CWnd* pParent /*=NULL*/) + : CDialog(CFcastWinDlg::IDD, pParent) + , m_ThreadOutput(NULL) + , m_ThreadOutputErr(NULL) + , m_FcastCmdLine(_T("")) + , m_ValueNLvl(_T("")) + , m_ValueDemux(_T("")) + , m_ValueTmpDir(_T("")) + , m_ValueTTL(_T("")) + , m_ValueFEC(_T("")) + , m_ValueRepeat(_T("")) + , m_ValuePathSend(_T("")) + , m_ValuePathRecv(_T("")) + , m_EXEFullPath(_T("")) + , m_ValueDSize(_T("")) + , m_ValueBW(_T("")) +{ + m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); +} + +void CFcastWinDlg::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_TABCTRL, m_TabCtrl); + DDX_Control(pDX, IDC_IPADDR, m_IPAddr); + DDX_Control(pDX, IDC_ZONE_ADDR, m_ZoneAddr); + DDX_Control(pDX, IDC_STATIC_ADDR, m_StaticAddr); + DDX_Control(pDX, IDC_STATIC_PORT, m_StaticPort); + DDX_Control(pDX, IDC_PORT, m_EditPort); + DDX_Control(pDX, IDC_ZONE_PATH, m_ZonePath); + DDX_Control(pDX, IDC_CHECK_RECURSIVE, m_CheckRecursive); + DDX_Control(pDX, IDC_BUTTON_BROWSE, m_BtnBrowse); + DDX_Control(pDX, IDC_STATIC_PATH, m_StaticPath); + DDX_Control(pDX, IDC_ZONE_OPT, m_ZoneOpt); + DDX_Control(pDX, IDC_CHECK_NLAYER, m_CheckNlayer); + DDX_Control(pDX, IDC_EDIT_NLVL, m_EditNlvl); + DDX_Control(pDX, IDC_STATIC_PROFILE, m_StaticProfile); + DDX_Control(pDX, IDC_COMBO_PROFILE, m_ComboProfile); + DDX_Control(pDX, IDC_CHECK_DEMUX, m_CheckDemux); + DDX_Control(pDX, IDC_EDIT_TSI, m_EditTsi); + DDX_Control(pDX, IDC_STATIC_OPTIMIZE, m_StaticOptimize); + DDX_Control(pDX, IDC_COMBO_OPTIMIZE, m_ComboOptimize); + DDX_Control(pDX, IDC_ZONE_OPTRCV, m_ZoneOptRcv); + DDX_Control(pDX, IDC_CHECK_TTL, m_CheckTTL); + DDX_Control(pDX, IDC_EDIT_TTL, m_EditTTL); + DDX_Control(pDX, IDC_CHECK_FEC, m_CheckFEC); + DDX_Control(pDX, IDC_EDIT_FEC, m_EditFec); + DDX_Control(pDX, IDC_CHECK_CONT, m_CheckCont); + DDX_Control(pDX, IDC_CHECK_HUGE, m_CheckHuge); + DDX_Control(pDX, IDC_CHECK_REPEAT, m_CheckRepeat); + DDX_Control(pDX, IDC_EDIT_NREPEAT, m_EditRepeat); + DDX_Control(pDX, IDC_STATIC_REPEAT, m_StaticRepeat); + DDX_Control(pDX, IDC_ZONE_OUTPUT, m_ZoneOutput); + DDX_Control(pDX, IDC_STATIC_TRACELVL, m_StaticTraceLvl); + DDX_Control(pDX, IDC_EDIT_TRACELVL, m_EditTraceLvl); + DDX_Control(pDX, IDC_STATIC_STATLVL, m_StaticStatLvl); + DDX_Control(pDX, IDC_EDIT_STATLVL, m_EditStatLvl); + DDX_Control(pDX, IDC_CHECK_SILENT, m_CheckSilent); + DDX_Control(pDX, IDC_STATIC_TMPDIR, m_StaticTmpDir); + DDX_Control(pDX, IDC_EDIT_TMPDIR, m_EditTmpDir); + DDX_Control(pDX, IDC_STATIC_IF, m_StaticIf); + DDX_Control(pDX, IDC_COMBO_IF, m_ComboIf); + DDX_Control(pDX, IDC_START, m_ButtonStart); + DDX_Control(pDX, IDC_EXPLORER1, m_IExplore); + DDX_Text(pDX, IDC_EDIT_CMDLINE, m_FcastCmdLine); + DDV_MaxChars(pDX, m_FcastCmdLine, 1024); + DDX_Text(pDX, IDC_EDIT_NLVL, m_ValueNLvl); + DDX_Text(pDX, IDC_EDIT_TSI, m_ValueDemux); + DDX_Text(pDX, IDC_EDIT_TMPDIR, m_ValueTmpDir); + DDX_Text(pDX, IDC_EDIT_TTL, m_ValueTTL); + DDX_Text(pDX, IDC_EDIT_FEC, m_ValueFEC); + DDX_Text(pDX, IDC_EDIT_NREPEAT, m_ValueRepeat); + DDX_Control(pDX, IDC_EDIT_PATH_RECV, m_EditPathRecv); + DDX_Control(pDX, IDC_EDIT_PATH_SEND, m_EditPathSend); + DDX_Text(pDX, IDC_EDIT_PATH_SEND, m_ValuePathSend); + DDX_Text(pDX, IDC_EDIT_PATH_RECV, m_ValuePathRecv); + DDX_Control(pDX, IDC_COMBO_OVERWRITE, m_ComboOverwrite); + DDX_Control(pDX, IDC_STATIC_OVERWRITE, m_StaticOverwrite); + DDX_Control(pDX, IDC_EDIT_STATUS, m_EditStatus); + DDX_Control(pDX, IDC_EDIT_CMDLINE, m_EditCmdLine); + DDX_Control(pDX, IDC_BTN_UPDATE, m_BtnUpdate); + DDX_Control(pDX, IDC_STATIC_CMDLINE, m_StatisCmdLine); + DDX_Control(pDX, IDC_EDIT_DSIZE, m_EditDSize); + DDX_Control(pDX, IDC_EDIT_BW, m_EditBW); + DDX_Control(pDX, IDC_STATIC_DSIZE, m_StaticDSize); + DDX_Control(pDX, IDC_STATIC_BW, m_StaticBW); + DDX_Text(pDX, IDC_EDIT_DSIZE, m_ValueDSize); + DDX_Text(pDX, IDC_EDIT_BW, m_ValueBW); + DDX_Control(pDX, IDC_CHECK_SINGLELAYER, m_CheckSingleLayer); +} + +BEGIN_MESSAGE_MAP(CFcastWinDlg, CDialog) + ON_WM_SYSCOMMAND() + ON_WM_PAINT() + ON_WM_QUERYDRAGICON() + //}}AFX_MSG_MAP + ON_BN_CLICKED(IDC_START, OnBnClickedStart) + ON_NOTIFY(TCN_SELCHANGE, IDC_TABCTRL, OnTcnSelchangeTabctrl) + ON_BN_CLICKED(IDC_CHECK_NLAYER, OnBnClickedCheckNlayer) + ON_BN_CLICKED(IDC_CHECK_SILENT, OnBnClickedCheckSilent) + ON_BN_CLICKED(IDC_CHECK_DEMUX, OnBnClickedCheckDemux) + ON_BN_CLICKED(IDC_CHECK_TTL, OnBnClickedCheckTtl) + ON_BN_CLICKED(IDC_CHECK_CONT, OnBnClickedCheckCont) + ON_BN_CLICKED(IDC_CHECK_REPEAT, OnBnClickedCheckRepeat) + ON_BN_CLICKED(IDC_CHECK_FEC, OnBnClickedCheckFec) + ON_BN_CLICKED(IDC_BUTTON_BROWSE, OnBnClickedButtonBrowse) + ON_WM_CLOSE() + ON_BN_CLICKED(IDC_BTN_UPDATE, OnParamsUpdate) + ON_EN_CHANGE(IDC_PORT, OnEnChangePort) + ON_NOTIFY(IPN_FIELDCHANGED, IDC_IPADDR, OnIpnFieldchangedIpaddr) + ON_EN_CHANGE(IDC_EDIT_TRACELVL, OnEnChangeEditTracelvl) + ON_BN_CLICKED(IDC_CHECK_RECURSIVE, OnBnClickedCheckRecursive) + ON_EN_CHANGE(IDC_EDIT_STATLVL, OnEnChangeEditStatlvl) + ON_EN_CHANGE(IDC_EDIT_PATH, OnEnChangeEditPath) + ON_EN_CHANGE(IDC_EDIT_NLVL, OnEnChangeEditNlvl) + ON_EN_CHANGE(IDC_EDIT_TSI, OnEnChangeEditTsi) + ON_CBN_SELCHANGE(IDC_COMBO_PROFILE, OnCbnSelchangeComboProfile) + ON_CBN_SELCHANGE(IDC_COMBO_OPTIMIZE, OnCbnSelchangeComboOptimize) + ON_EN_CHANGE(IDC_EDIT_TMPDIR, OnEnChangeEditTmpdir) + ON_EN_CHANGE(IDC_EDIT_TTL, OnEnChangeEditTtl) + ON_EN_CHANGE(IDC_EDIT_FEC, OnEnChangeEditFec) + ON_BN_CLICKED(IDC_CHECK_HUGE, OnBnClickedCheckHuge) + ON_BN_CLICKED(IDC_CHECK_OVERWRITE, OnBnClickedCheckOverwrite) + ON_EN_CHANGE(IDC_EDIT_PATH_SEND, OnEnChangeEditPathSend) + ON_EN_CHANGE(IDC_EDIT_PATH_RECV, OnEnChangeEditPathRecv) + ON_CBN_SELCHANGE(IDC_COMBO_OVERWRITE, OnCbnSelchangeComboOverwrite) + ON_EN_CHANGE(IDC_EDIT_DSIZE, OnEnChangeEditDsize) + ON_EN_CHANGE(IDC_EDIT_BW, OnEnChangeEditBw) + ON_BN_CLICKED(IDC_CHECK_SINGLELAYER, OnBnClickedCheckSinglelayer) +END_MESSAGE_MAP() + + +// gestionnaires de messages pour CFcastWinDlg +BOOL CFcastWinDlg::OnInitDialog() +{ + CDialog::OnInitDialog(); + ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); + ASSERT(IDM_ABOUTBOX < 0xF000); + CMenu* pSysMenu = GetSystemMenu(FALSE); + if (pSysMenu != NULL) + { + CString strAboutMenu; + strAboutMenu.LoadString(IDS_ABOUTBOX); + if (!strAboutMenu.IsEmpty()) + { + pSysMenu->AppendMenu(MF_SEPARATOR); + pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); + } + } + SetIcon(m_hIcon, TRUE); // Définir une grande icône + SetIcon(m_hIcon, FALSE); // Définir une petite icône + + // TODO : ajoutez ici une initialisation supplémentaire + m_TabCtrl.InsertItem(IDTAB_SEND, "Send"); + m_TabCtrl.InsertItem(IDTAB_RECV, "Receive"); + m_TabCtrl.InsertItem(IDTAB_HELP, "Help"); + ShowControlForTab(0); + m_CheckNlayer.SetCheck(BST_UNCHECKED); + m_EditNlvl.EnableWindow(FALSE); + m_EditNlvl.SetWindowText("5"); + m_EditTraceLvl.EnableWindow(); + m_EditTraceLvl.SetWindowText(""); + m_EditStatLvl.EnableWindow(); + m_EditStatLvl.SetWindowText(""); + m_CheckDemux.SetCheck(BST_UNCHECKED); + m_EditTsi.EnableWindow(FALSE); + m_EditTsi.SetWindowText("0"); + m_EditTmpDir.SetWindowText(""); + m_CheckTTL.SetCheck(BST_UNCHECKED); + m_EditTTL.EnableWindow(FALSE); + m_EditTTL.SetWindowText("1"); + m_CheckRepeat.SetCheck(BST_UNCHECKED); + m_EditRepeat.EnableWindow(FALSE); + m_EditRepeat.SetWindowText("3"); + m_CheckFEC.SetCheck(BST_UNCHECKED); + m_EditFec.EnableWindow(FALSE); + m_EditFec.SetWindowText("0"); + m_ComboOverwrite.InsertString(0, "Ask"); + m_ComboOverwrite.InsertString(1, "Never"); + m_ComboOverwrite.InsertString(2, "Always"); + m_ComboOverwrite.SetCurSel(0); + m_ComboOptimize.InsertString(0, "DEFAULT"); + m_ComboOptimize.InsertString(1, "Speed"); + m_ComboOptimize.InsertString(2, "Space"); + m_ComboOptimize.InsertString(3, "CPU"); + m_ComboOptimize.SetCurSel(0); + m_ComboProfile.InsertString(0, "DEFAULT"); + m_ComboProfile.InsertString(1, "Low Internet"); + m_ComboProfile.InsertString(2, "Medium Internet"); + m_ComboProfile.InsertString(3, "High Internet"); + m_ComboProfile.InsertString(4, "High LAN"); + m_ComboProfile.InsertString(5, "Custom..."); + m_ComboProfile.SetCurSel(0); + m_EditDSize.EnableWindow(FALSE); + m_EditBW.EnableWindow(FALSE); + m_IPAddr.SetAddress(224, 100, 101, 102); + m_EditPort.SetWindowText("2002"); + CString MyCmdLine = GetCommandLine(); + MyCmdLine.Trim('\"'); + + int ind2, ind = MyCmdLine.Find('\\', 0); + while( ind != -1) + { + ind2 = ind; + ind = MyCmdLine.Find('\\', ind2+1); + } + m_EXEFullPath = MyCmdLine.Left(ind2); + m_ValuePathSend = "c:\\foo.bar"; + m_ValuePathRecv = m_EXEFullPath; + + m_IExplore.Navigate(m_EXEFullPath + "\\fcast.html", 0, (struct tagVARIANT *)"_SELF", NULL, NULL); + UpdateData(FALSE); + OnParamsUpdate(); + return TRUE; +} + + + +void CFcastWinDlg::OnBnClickedStart() +{ + UpdateData(TRUE); + + if(m_TabCtrl.GetCurSel() == IDTAB_RECV) + { + if(!m_ValuePathRecv.IsEmpty() && PathFileExists(m_ValuePathRecv) && PathIsDirectory(m_ValuePathRecv)) + { + m_EditStatus.SetWindowText("Executing fcast " + m_FcastCmdLine + "\r\n(working dir: " + m_ValuePathRecv + ")."); + ShellExecute(NULL, NULL, m_EXEFullPath + "\\fcast.exe", m_FcastCmdLine, m_ValuePathRecv, SW_SHOW ); + } + else + { + MessageBox("Invalid destination directory: " + m_ValuePathRecv, "Error", MB_OK+MB_ICONERROR); + } + } + else if(m_TabCtrl.GetCurSel() == IDTAB_SEND) + { + if(!m_ValuePathSend.IsEmpty() && PathFileExists(m_ValuePathSend)) + { + CString PathSendFrom, ObjSendName; + int ind2=-1; int ind; + + ObjSendName.Empty(); + + if(PathIsDirectory(m_ValuePathSend)) + { + if(m_ValuePathSend[m_ValuePathSend.GetLength()-1] == '\\') + { + m_ValuePathSend = m_ValuePathSend.Left(m_ValuePathSend.GetLength()-1); + } + ind = m_ValuePathSend.Find('\\', 0); + while( ind != -1) + { + ind2 = ind; + ind = m_ValuePathSend.Find('\\', ind2+1); + } + if(ind2>=0) + { + PathSendFrom = m_ValuePathSend.Left(ind2+1); + if(ind2+1 < m_ValuePathSend.GetLength()) + { + ObjSendName = m_ValuePathSend.Right(m_ValuePathSend.GetLength() - ind2 - 1); + } + } + else + { + PathSendFrom = m_ValuePathSend; + ObjSendName = "."; + } + } + else + { + ind = m_ValuePathSend.Find('\\', 0); + while( ind != -1) + { + ind2 = ind; + ind = m_ValuePathSend.Find('\\', ind2+1); + } + if(ind2>=0) + { + PathSendFrom = m_ValuePathSend.Left(ind2+1); + if(ind2+1 < m_ValuePathSend.GetLength()) + { + ObjSendName = m_ValuePathSend.Right(m_ValuePathSend.GetLength() - ind2 - 1); + } + } + else + { + PathSendFrom.Empty(); + ObjSendName = m_ValuePathSend; + } + } + + m_EditStatus.SetWindowText("Executing fcast " + m_FcastCmdLine + " " + ObjSendName + "\r\n(working dir: " + PathSendFrom + ")."); + ShellExecute(NULL, NULL, m_EXEFullPath + "\\fcast.exe", m_FcastCmdLine + " " + ObjSendName, PathSendFrom, SW_SHOW ); + } + else + { + MessageBox("No such file or directory: " + m_ValuePathSend, "Error", MB_OK+MB_ICONERROR); + } + } + +} + + +void CFcastWinDlg::OnTcnSelchangeTabctrl(NMHDR *pNMHDR, LRESULT *pResult) +{ + int nTab = m_TabCtrl.GetCurSel(); + ShowControlForTab(nTab); + *pResult = 0; +} + + +void CFcastWinDlg::OnBnClickedCheckNlayer() +{ + if(m_CheckNlayer.GetCheck() == BST_CHECKED) + { + m_EditNlvl.EnableWindow(); + m_CheckSingleLayer.SetCheck( BST_UNCHECKED); + } + else + { + m_EditNlvl.EnableWindow(FALSE); + } + + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckSilent() +{ + if(m_CheckSilent.GetCheck()) + { + m_EditTraceLvl.EnableWindow(FALSE); + m_EditStatLvl.EnableWindow(FALSE); + } + else + { + m_EditTraceLvl.EnableWindow(); + m_EditStatLvl.EnableWindow(); + } + + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckDemux() +{ + if(m_CheckDemux.GetCheck()) + { + m_EditTsi.EnableWindow(); + } + else + { + m_EditTsi.EnableWindow(FALSE); + } + + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckTtl() +{ + if(m_CheckTTL.GetCheck()) + { + m_EditTTL.EnableWindow(); + } + else + { + m_EditTTL.EnableWindow(FALSE); + } + + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckCont() +{ + if(m_CheckCont.GetCheck()) + { + m_CheckRepeat.EnableWindow(FALSE); + m_EditRepeat.EnableWindow(FALSE); + m_StaticRepeat.EnableWindow(FALSE); + } + else + { + m_CheckRepeat.EnableWindow(); + if(m_CheckRepeat.GetCheck()) { + m_EditRepeat.EnableWindow(); + } + else { + m_EditRepeat.EnableWindow(FALSE); + } + m_StaticRepeat.EnableWindow(); + } + + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckRepeat() +{ + if(m_CheckRepeat.GetCheck()) + { + m_EditRepeat.EnableWindow(); + } + else + { + m_EditRepeat.EnableWindow(FALSE); + } + + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckFec() +{ + if(m_CheckFEC.GetCheck()) + { + m_EditFec.EnableWindow(); + } + else + { + m_EditFec.EnableWindow(FALSE); + } + + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedButtonBrowse() +{ + BROWSEINFO MyBrowseInfo; + TCHAR MyShPath[MAX_PATH]; + + ZeroMemory(&MyBrowseInfo, sizeof(MyBrowseInfo)); + if(m_TabCtrl.GetCurSel() == IDTAB_SEND) + { + MyBrowseInfo.lpszTitle = "Select a file or directory to send"; + MyBrowseInfo.ulFlags = BIF_BROWSEINCLUDEFILES | BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; + } + else if(m_TabCtrl.GetCurSel() == IDTAB_RECV) + { + MyBrowseInfo.lpszTitle = "Select a directory to store received files to"; + MyBrowseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE; + } + + MyBrowseInfo.hwndOwner = this->m_hWnd; + MyBrowseInfo.pidlRoot = NULL; + MyBrowseInfo.pszDisplayName = NULL; + LPITEMIDLIST MyItem = SHBrowseForFolder(&MyBrowseInfo); + if( MyItem!=NULL ) + { + SHGetPathFromIDList(MyItem, MyShPath); + if(m_TabCtrl.GetCurSel() == IDTAB_SEND) + { + m_ValuePathSend = MyShPath; + } + else if(m_TabCtrl.GetCurSel() == IDTAB_RECV) + { + if(PathFileExists(MyShPath) && PathIsDirectory(MyShPath)) + { + m_ValuePathRecv = MyShPath; + } + } + UpdateData(FALSE); + OnParamsUpdate(); + } + +} + +void CFcastWinDlg::OnClose() +{ + CDialog::OnClose(); +} + +void CFcastWinDlg::OnParamsUpdate() +{ + CString Args, ValuePort; + BYTE IPField1, IPField2, IPField3, IPField4; + UpdateData(TRUE); + + if(m_TabCtrl.GetCurSel() == IDTAB_SEND) + { + m_FcastCmdLine = "-send -P"; + } + else if(m_TabCtrl.GetCurSel() == IDTAB_RECV) + { + m_FcastCmdLine = "-recv -P"; + } + else + { + return; + } + + m_EditPort.GetWindowText(ValuePort); + + m_IPAddr.GetAddress(IPField1, IPField2, IPField3, IPField4); + Args.Format(" -a%d.%d.%d.%d/%s",IPField1 , IPField2 , IPField3 , IPField4, ValuePort); + + switch( m_ComboOptimize.GetCurSel()) + { + case 0: + break; + case 1: + Args += " -ospeed"; + break; + case 2: + Args += " -ospace"; + break; + case 3: + Args += " -ocpu"; + break; + default: + break; + } + + switch( m_ComboProfile.GetCurSel()) + { + case 0: + break; + case 1: + Args += " -plow"; + break; + case 2: + Args += " -pmed"; + break; + case 3: + Args += " -phig"; + break; + case 4: + Args += " -plan"; + break; + case 5: + Args += " -p" + m_ValueDSize; + if(m_TabCtrl.GetCurSel()==IDTAB_SEND && m_ValueBW!="") + { + Args += "/" + m_ValueBW; + } + default: + break; + } + + if( m_CheckNlayer.GetCheck() == BST_CHECKED && m_ValueNLvl!="" ) + { + Args += " -l" + m_ValueNLvl; + } + else if ( m_CheckSingleLayer.GetCheck() == BST_CHECKED ) + { + Args += " -singlelayer"; + } + + + if(m_CheckSilent.GetCheck() == BST_CHECKED) + { + Args += " -silent"; + } + else + { + CString ValueTraceLvl; + CString ValueStatLvl; + m_EditTraceLvl.GetWindowText(ValueTraceLvl); + m_EditStatLvl.GetWindowText(ValueStatLvl); + + if( ValueTraceLvl != "" ) + { + Args += " -v" + ValueTraceLvl; + } + if( ValueStatLvl != "" ) + { + Args += " -stat" + ValueStatLvl; + } + } + + if(m_CheckDemux.GetCheck() == BST_CHECKED && m_ValueDemux!="") + { + Args += " -demux" + m_ValueDemux; + } + + if(m_ValueTmpDir!="") + { + Args += " -tmpdir" + m_ValueTmpDir; + } + + if(m_TabCtrl.GetCurSel() == IDTAB_SEND) + { + if(!m_ValuePathSend.IsEmpty()) + { + if(PathFileExists(m_ValuePathSend) && PathIsDirectory(m_ValuePathSend)) + { + m_CheckRecursive.EnableWindow(TRUE); + m_CheckRecursive.SetCheck(BST_CHECKED); + } + else if(PathFileExists(m_ValuePathSend)) + { + m_CheckRecursive.EnableWindow(TRUE); + m_CheckRecursive.SetCheck(BST_UNCHECKED); + } + else + { + m_CheckRecursive.SetCheck(BST_UNCHECKED); + m_CheckRecursive.EnableWindow(FALSE); + } + } + + if(m_CheckRecursive.GetCheck() == BST_CHECKED) + { + Args += " -R"; + } + if( m_CheckTTL.GetCheck() && m_ValueTTL!="") + { + Args += " -t" + m_ValueTTL; + } + if( m_CheckFEC.GetCheck() && m_ValueFEC!="") + { + Args += " -fec" + m_ValueFEC; + } + if( m_CheckHuge.GetCheck() ) + { + Args += " -huge"; + } + if(m_CheckCont.GetCheck()) + { + Args += " -cont"; + } + else if( m_CheckRepeat.GetCheck() && m_ValueRepeat!="") + { + Args += " -repeat" + m_ValueRepeat; + } + } + else if(m_TabCtrl.GetCurSel() == IDTAB_RECV) + { + switch( m_ComboOverwrite.GetCurSel()) + { + case 0: + Args += " -int"; + break; + case 1: + Args += " -never"; + break; + case 2: + Args += " -force"; + break; + default: + break; + } + } + + m_FcastCmdLine += Args; + UpdateData(FALSE); + +} + + + +void CFcastWinDlg::OnEnChangePort() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnIpnFieldchangedIpaddr(NMHDR *pNMHDR, LRESULT *pResult) +{ + LPNMIPADDRESS pIPAddr = reinterpret_cast(pNMHDR); + OnParamsUpdate(); + *pResult = 0; +} + +void CFcastWinDlg::OnEnChangeEditTracelvl() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckRecursive() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditStatlvl() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditPath() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditNlvl() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditTsi() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnCbnSelchangeComboProfile() +{ + if(m_ComboProfile.GetCurSel()==5) + { + m_EditDSize.EnableWindow(TRUE); + m_EditBW.EnableWindow(TRUE); + } + else + { + m_EditDSize.EnableWindow(FALSE); + m_EditBW.EnableWindow(FALSE); + } + + + OnParamsUpdate(); +} + +void CFcastWinDlg::OnCbnSelchangeComboOptimize() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditTmpdir() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditTtl() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditFec() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckHuge() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckOverwrite() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::ShowControlForTab(int nTab) +{ + switch(nTab) + { + case IDTAB_SEND: + m_ButtonStart.ShowWindow(SW_SHOW); + m_ButtonStart.SetWindowText("&Send Now!"); + m_IPAddr.ShowWindow(SW_SHOW); + m_StaticAddr.ShowWindow(SW_SHOW); + m_ZoneAddr.ShowWindow(SW_SHOW); + m_StaticPort.ShowWindow(SW_SHOW); + m_EditPort.ShowWindow(SW_SHOW); + m_ZonePath.SetWindowText("File(s) to send"); + m_ZonePath.ShowWindow(SW_SHOW); + m_IExplore.put_Height(0); + m_IExplore.put_Width(0); + + m_CheckRecursive.ShowWindow(SW_SHOW); + m_BtnBrowse.ShowWindow(SW_SHOW); + m_EditPathRecv.ShowWindow(SW_HIDE); + m_EditPathSend.ShowWindow(SW_SHOW); + m_StaticPath.ShowWindow(SW_SHOW); + m_ComboOverwrite.ShowWindow(SW_HIDE); + m_StaticOverwrite.ShowWindow(SW_HIDE); + m_ZoneOpt.ShowWindow(SW_SHOW); + m_ZoneOptRcv.ShowWindow(SW_HIDE); + m_CheckNlayer.ShowWindow(SW_SHOW); + m_EditNlvl.ShowWindow(SW_SHOW); + m_CheckSingleLayer.ShowWindow(SW_SHOW); + m_StaticProfile.ShowWindow(SW_SHOW); + m_ComboProfile.ShowWindow(SW_SHOW); + m_EditDSize.ShowWindow(SW_SHOW); + m_StaticDSize.ShowWindow(SW_SHOW); + m_EditBW.ShowWindow(SW_SHOW); + m_StaticBW.ShowWindow(SW_SHOW); + m_CheckDemux.ShowWindow(SW_SHOW); + m_EditTsi.ShowWindow(SW_SHOW); + m_StaticOptimize.ShowWindow(SW_SHOW); + m_ComboOptimize.ShowWindow(SW_SHOW); + m_EditStatus.ShowWindow(SW_SHOW); + m_EditStatus.SetWindowText("Ready."); + m_EditCmdLine.ShowWindow(SW_SHOW); + m_BtnUpdate.ShowWindow(SW_SHOW); + m_StatisCmdLine.ShowWindow(SW_SHOW); + + m_CheckTTL.ShowWindow(SW_SHOW); + m_EditTTL.ShowWindow(SW_SHOW); + m_CheckFEC.ShowWindow(SW_SHOW); + m_EditFec.ShowWindow(SW_SHOW); + m_CheckCont.ShowWindow(SW_SHOW); + m_CheckHuge.ShowWindow(SW_SHOW); + m_CheckRepeat.ShowWindow(SW_SHOW); + m_EditRepeat.ShowWindow(SW_SHOW); + m_StaticRepeat.ShowWindow(SW_SHOW); + + m_ZoneOutput.ShowWindow(SW_SHOW); + m_StaticTraceLvl.ShowWindow(SW_SHOW); + m_EditTraceLvl.ShowWindow(SW_SHOW); + m_StaticStatLvl.ShowWindow(SW_SHOW); + m_EditStatLvl.ShowWindow(SW_SHOW); + m_CheckSilent.ShowWindow(SW_SHOW); + + m_StaticTmpDir.ShowWindow(SW_SHOW); + m_EditTmpDir.ShowWindow(SW_SHOW); + m_StaticIf.ShowWindow(SW_SHOW); + m_ComboIf.ShowWindow(SW_SHOW); + + OnParamsUpdate(); + + break; + + case IDTAB_RECV: + m_ButtonStart.ShowWindow(SW_SHOW); + m_ButtonStart.SetWindowText("&Receive Now!"); + m_IPAddr.ShowWindow(SW_SHOW); + m_StaticAddr.ShowWindow(SW_SHOW); + m_ZoneAddr.ShowWindow(SW_SHOW); + m_StaticPort.ShowWindow(SW_SHOW); + m_EditPort.ShowWindow(SW_SHOW); + m_ZonePath.SetWindowText("Destination Folder"); + m_ZonePath.ShowWindow(SW_SHOW); + m_IExplore.put_Height(0); + m_IExplore.put_Width(0); + + m_CheckRecursive.ShowWindow(SW_HIDE); + m_BtnBrowse.ShowWindow(SW_SHOW); + m_EditPathRecv.ShowWindow(SW_SHOW); + m_EditPathSend.ShowWindow(SW_HIDE); + m_StaticPath.ShowWindow(SW_SHOW); + m_ComboOverwrite.ShowWindow(SW_SHOW); + m_StaticOverwrite.ShowWindow(SW_SHOW); + m_ZoneOpt.ShowWindow(SW_HIDE); + m_ZoneOptRcv.ShowWindow(SW_SHOW); + m_CheckNlayer.ShowWindow(SW_SHOW); + m_EditNlvl.ShowWindow(SW_SHOW); + m_CheckSingleLayer.ShowWindow(SW_SHOW); + m_StaticProfile.ShowWindow(SW_SHOW); + m_ComboProfile.ShowWindow(SW_SHOW); + m_EditDSize.ShowWindow(SW_SHOW); + m_StaticDSize.ShowWindow(SW_SHOW); + m_EditBW.ShowWindow(SW_HIDE); + m_StaticBW.ShowWindow(SW_HIDE); + m_CheckDemux.ShowWindow(SW_SHOW); + m_EditTsi.ShowWindow(SW_SHOW); + m_StaticOptimize.ShowWindow(SW_SHOW); + m_ComboOptimize.ShowWindow(SW_SHOW); + m_CheckTTL.ShowWindow(SW_HIDE); + m_EditTTL.ShowWindow(SW_HIDE); + m_CheckFEC.ShowWindow(SW_HIDE); + m_EditFec.ShowWindow(SW_HIDE); + m_CheckCont.ShowWindow(SW_HIDE); + m_CheckHuge.ShowWindow(SW_HIDE); + m_CheckRepeat.ShowWindow(SW_HIDE); + m_EditRepeat.ShowWindow(SW_HIDE); + m_StaticRepeat.ShowWindow(SW_HIDE); + m_EditStatus.ShowWindow(SW_SHOW); + m_EditStatus.SetWindowText("Ready."); + m_EditCmdLine.ShowWindow(SW_SHOW); + m_BtnUpdate.ShowWindow(SW_SHOW); + m_StatisCmdLine.ShowWindow(SW_SHOW); + + m_ZoneOutput.ShowWindow(SW_SHOW); + m_StaticTraceLvl.ShowWindow(SW_SHOW); + m_EditTraceLvl.ShowWindow(SW_SHOW); + m_StaticStatLvl.ShowWindow(SW_SHOW); + m_EditStatLvl.ShowWindow(SW_SHOW); + m_CheckSilent.ShowWindow(SW_SHOW); + + m_StaticTmpDir.ShowWindow(SW_SHOW); + m_EditTmpDir.ShowWindow(SW_SHOW); + m_StaticIf.ShowWindow(SW_SHOW); + m_ComboIf.ShowWindow(SW_SHOW); + + OnParamsUpdate(); + + break; + + case IDTAB_HELP: + m_ButtonStart.ShowWindow(SW_HIDE); + m_IPAddr.ShowWindow(SW_HIDE); + m_StaticAddr.ShowWindow(SW_HIDE); + m_ZoneAddr.ShowWindow(SW_HIDE); + m_StaticPort.ShowWindow(SW_HIDE); + m_EditPort.ShowWindow(SW_HIDE); + m_ZonePath.ShowWindow(SW_HIDE); + m_IExplore.put_Width(474); + m_IExplore.put_Height(480); + + m_CheckRecursive.ShowWindow(SW_HIDE); + m_BtnBrowse.ShowWindow(SW_HIDE); + m_EditPathRecv.ShowWindow(SW_HIDE); + m_EditPathSend.ShowWindow(SW_HIDE); + m_StaticPath.ShowWindow(SW_HIDE); + m_ComboOverwrite.ShowWindow(SW_HIDE); + m_StaticOverwrite.ShowWindow(SW_HIDE); + m_ZoneOpt.ShowWindow(SW_HIDE); + m_ZoneOptRcv.ShowWindow(SW_HIDE); + m_CheckNlayer.ShowWindow(SW_HIDE); + m_EditNlvl.ShowWindow(SW_HIDE); + m_CheckSingleLayer.ShowWindow(SW_HIDE); + m_StaticProfile.ShowWindow(SW_HIDE); + m_ComboProfile.ShowWindow(SW_HIDE); + m_EditDSize.ShowWindow(SW_HIDE); + m_StaticDSize.ShowWindow(SW_HIDE); + m_EditBW.ShowWindow(SW_HIDE); + m_StaticBW.ShowWindow(SW_HIDE); + m_CheckDemux.ShowWindow(SW_HIDE); + m_EditTsi.ShowWindow(SW_HIDE); + m_StaticOptimize.ShowWindow(SW_HIDE); + m_ComboOptimize.ShowWindow(SW_HIDE); + m_CheckTTL.ShowWindow(SW_HIDE); + m_EditTTL.ShowWindow(SW_HIDE); + m_CheckFEC.ShowWindow(SW_HIDE); + m_EditFec.ShowWindow(SW_HIDE); + m_CheckCont.ShowWindow(SW_HIDE); + m_CheckHuge.ShowWindow(SW_HIDE); + m_CheckRepeat.ShowWindow(SW_HIDE); + m_EditRepeat.ShowWindow(SW_HIDE); + m_StaticRepeat.ShowWindow(SW_HIDE); + m_EditStatus.ShowWindow(SW_HIDE); + m_EditCmdLine.ShowWindow(SW_HIDE); + m_BtnUpdate.ShowWindow(SW_HIDE); + m_StatisCmdLine.ShowWindow(SW_HIDE); + + m_ZoneOutput.ShowWindow(SW_HIDE); + m_StaticTraceLvl.ShowWindow(SW_HIDE); + m_EditTraceLvl.ShowWindow(SW_HIDE); + m_StaticStatLvl.ShowWindow(SW_HIDE); + m_EditStatLvl.ShowWindow(SW_HIDE); + m_CheckSilent.ShowWindow(SW_HIDE); + + m_StaticTmpDir.ShowWindow(SW_HIDE); + m_EditTmpDir.ShowWindow(SW_HIDE); + m_StaticIf.ShowWindow(SW_HIDE); + m_ComboIf.ShowWindow(SW_HIDE); + break; + default: + MessageBox("Erreur de tabulation!", "Erreur!", MB_ICONERROR); + } +} + + +void CFcastWinDlg::OnSysCommand(UINT nID, LPARAM lParam) +{ + if ((nID & 0xFFF0) == IDM_ABOUTBOX) + { + CAboutDlg dlgAbout; + dlgAbout.DoModal(); + } + else + { + CDialog::OnSysCommand(nID, lParam); + } +} + +void CFcastWinDlg::OnPaint() +{ + if (IsIconic()) + { + CPaintDC dc(this); // contexte de périphérique pour la peinture + + SendMessage(WM_ICONERASEBKGND, reinterpret_cast(dc.GetSafeHdc()), 0); + + // Centrer l'icône dans le rectangle client + int cxIcon = GetSystemMetrics(SM_CXICON); + int cyIcon = GetSystemMetrics(SM_CYICON); + CRect rect; + GetClientRect(&rect); + int x = (rect.Width() - cxIcon + 1) / 2; + int y = (rect.Height() - cyIcon + 1) / 2; + + // Dessiner l'icône + dc.DrawIcon(x, y, m_hIcon); + } + else + { + CDialog::OnPaint(); + } +} + +// Le système appelle cette fonction pour obtenir le curseur à afficher lorsque l'utilisateur fait glisser +// la fenêtre réduite. +HCURSOR CFcastWinDlg::OnQueryDragIcon() +{ + return static_cast(m_hIcon); +} +void CFcastWinDlg::OnEnChangeEditPathSend() +{ + m_CheckRecursive.EnableWindow(TRUE); + m_CheckRecursive.SetCheck(BST_UNCHECKED); + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditPathRecv() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnCbnSelchangeComboOverwrite() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditDsize() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnEnChangeEditBw() +{ + OnParamsUpdate(); +} + +void CFcastWinDlg::OnBnClickedCheckSinglelayer() +{ + if(m_CheckSingleLayer.GetCheck() == BST_CHECKED) + { + m_CheckNlayer.SetCheck(BST_UNCHECKED); + m_EditNlvl.EnableWindow(FALSE); + } + OnParamsUpdate(); +} diff --git a/fcastwin/FcastWinDlg.h b/fcastwin/FcastWinDlg.h new file mode 100644 index 0000000..e6e4ce4 --- /dev/null +++ b/fcastwin/FcastWinDlg.h @@ -0,0 +1,161 @@ +// FcastWinDlg.h : fichier d'en-tête +// + +#pragma once +#include "afxcmn.h" +#include "afxwin.h" +#include "IExplore.h" + + +#define STATUS_NBLINE 30 + +#define IDTAB_SEND 0 +#define IDTAB_RECV 1 +#define IDTAB_HELP 2 + +// boîte de dialogue CFcastWinDlg +class CFcastWinDlg : public CDialog +{ +// Construction +public: + CFcastWinDlg(CWnd* pParent = NULL); // constructeur standard + +// Données de la boîte de dialogue + enum { IDD = IDD_FCASTWIN_DIALOG }; + + protected: + virtual void DoDataExchange(CDataExchange* pDX); // prise en charge de DDX/DDV + + +// Implémentation +protected: + HICON m_hIcon; + + // Fonctions générées de la table des messages + virtual BOOL OnInitDialog(); + afx_msg void OnSysCommand(UINT nID, LPARAM lParam); + afx_msg void OnPaint(); + afx_msg HCURSOR OnQueryDragIcon(); + DECLARE_MESSAGE_MAP() + // Control RichEdit status + CRichEditCtrl m_StatusWin; +public: + afx_msg void OnBnClickedStart(); + static UINT ThreadChildStdOut(LPVOID param); + void ThreadChildStdOut(void); + static UINT ThreadChildStdErr(LPVOID param); + void ThreadChildStdErr(void); + +private: + CWinThread* m_ThreadOutput; +public: + afx_msg void OnBnClickedButtonCommand(); + +private: + CWinThread* m_ThreadOutputErr; +public: + CTabCtrl m_TabCtrl; + afx_msg void OnTcnSelchangeTabctrl(NMHDR *pNMHDR, LRESULT *pResult); + CIPAddressCtrl m_IPAddr; +private: + void ShowControlForTab(int nTab); +public: + CStatic m_ZoneAddr; + CStatic m_StaticAddr; + CStatic m_StaticPort; + CEdit m_EditPort; + CStatic m_ZonePath; + CButton m_BtnBrowse; + CButton m_CheckRecursive; + CStatic m_StaticPath; + CStatic m_ZoneOpt; + CButton m_CheckNlayer; + CEdit m_EditNlvl; + CStatic m_StaticProfile; + CComboBox m_ComboProfile; + CButton m_CheckDemux; + CEdit m_EditTsi; + CStatic m_StaticOptimize; + CComboBox m_ComboOptimize; + CStatic m_ZoneOptRcv; + CButton m_CheckTTL; + CEdit m_EditTTL; + CButton m_CheckFEC; + CEdit m_EditFec; + CButton m_CheckCont; + CButton m_CheckHuge; + CButton m_CheckRepeat; + CEdit m_EditRepeat; + CStatic m_StaticRepeat; + CStatic m_ZoneOutput; + CStatic m_StaticTraceLvl; + CEdit m_EditTraceLvl; + CStatic m_StaticStatLvl; + CEdit m_EditStatLvl; + CButton m_CheckSilent; + CStatic m_StaticTmpDir; + CEdit m_EditTmpDir; + CStatic m_StaticIf; + CComboBox m_ComboIf; + afx_msg void OnBnClickedCheckNlayer(); + afx_msg void OnBnClickedCheckSilent(); + afx_msg void OnBnClickedCheckDemux(); + afx_msg void OnBnClickedCheckTtl(); + afx_msg void OnBnClickedCheckCont(); + afx_msg void OnBnClickedCheckRepeat(); + afx_msg void OnBnClickedCheckFec(); + afx_msg void OnBnClickedButtonBrowse(); + CButton m_ButtonStart; + CExplorer1 m_IExplore; + afx_msg void OnClose(); + afx_msg void OnParamsUpdate(); + afx_msg void OnEnChangePort(); + afx_msg void OnIpnFieldchangedIpaddr(NMHDR *pNMHDR, LRESULT *pResult); + afx_msg void OnEnChangeEditTracelvl(); + afx_msg void OnBnClickedCheckRecursive(); +public: + CString m_FcastCmdLine; + afx_msg void OnEnChangeEditStatlvl(); + afx_msg void OnEnChangeEditPath(); + CString m_ValueNLvl; + afx_msg void OnEnChangeEditNlvl(); + CString m_ValueDemux; + afx_msg void OnEnChangeEditTsi(); + afx_msg void OnCbnSelchangeComboProfile(); + afx_msg void OnCbnSelchangeComboOptimize(); + afx_msg void OnEnChangeEditTmpdir(); + CString m_ValueTmpDir; + afx_msg void OnEnChangeEditTtl(); + CString m_ValueTTL; + CString m_ValueFEC; + afx_msg void OnEnChangeEditFec(); + afx_msg void OnBnClickedCheckHuge(); + CString m_ValueRepeat; + afx_msg void OnBnClickedCheckOverwrite(); + CEdit m_EditPathRecv; + CEdit m_EditPathSend; + CString m_ValuePathSend; + CString m_ValuePathRecv; + afx_msg void OnEnChangeEditPathSend(); + afx_msg void OnEnChangeEditPathRecv(); +private: + CString m_EXEFullPath; +public: + CComboBox m_ComboOverwrite; + CStatic m_StaticOverwrite; + afx_msg void OnCbnSelchangeComboOverwrite(); + CEdit m_EditStatus; + CEdit m_EditCmdLine; + CButton m_BtnUpdate; + CStatic m_StatisCmdLine; + CEdit m_EditDSize; + CEdit m_EditBW; + CStatic m_StaticDSize; + CStatic m_StaticBW; + CString m_ValueDSize; + CString m_ValueBW; + afx_msg void OnEnChangeEditDsize(); + afx_msg void OnEnChangeEditBw(); + CButton m_CheckSingleLayer; + afx_msg void OnBnClickedCheckSinglelayer(); +}; diff --git a/fcastwin/IExplore.cpp b/fcastwin/IExplore.cpp new file mode 100644 index 0000000..e6b3448 --- /dev/null +++ b/fcastwin/IExplore.cpp @@ -0,0 +1,19 @@ +// Machine generated IDispatch wrapper class(es) created by Microsoft Visual C++ + +// NOTE: Do not modify the contents of this file. If this class is regenerated by +// Microsoft Visual C++, your modifications will be overwritten. + + +#include "stdafx.h" +#include "IExplore.h" + +///////////////////////////////////////////////////////////////////////////// +// CExplorer1 + +IMPLEMENT_DYNCREATE(CExplorer1, CWnd) + +///////////////////////////////////////////////////////////////////////////// +// CExplorer1 properties + +///////////////////////////////////////////////////////////////////////////// +// CExplorer1 operations diff --git a/fcastwin/IExplore.h b/fcastwin/IExplore.h new file mode 100644 index 0000000..7a94c3c --- /dev/null +++ b/fcastwin/IExplore.h @@ -0,0 +1,511 @@ +#pragma once + +// Machine generated IDispatch wrapper class(es) created by Microsoft Visual C++ + +// NOTE: Do not modify the contents of this file. If this class is regenerated by +// Microsoft Visual C++, your modifications will be overwritten. + +///////////////////////////////////////////////////////////////////////////// +// CExplorer1 wrapper class + +class CExplorer1 : public CWnd +{ +protected: + DECLARE_DYNCREATE(CExplorer1) +public: + CLSID const& GetClsid() + { + static CLSID const clsid + = { 0x8856F961, 0x340A, 0x11D0, { 0xA9, 0x6B, 0x0, 0xC0, 0x4F, 0xD7, 0x5, 0xA2 } }; + return clsid; + } + virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, + const RECT& rect, CWnd* pParentWnd, UINT nID, + CCreateContext* pContext = NULL) + { + return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID); + } + + BOOL Create(LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, + UINT nID, CFile* pPersist = NULL, BOOL bStorage = FALSE, + BSTR bstrLicKey = NULL) + { + return CreateControl(GetClsid(), lpszWindowName, dwStyle, rect, pParentWnd, nID, + pPersist, bStorage, bstrLicKey); + } + +// Attributes +public: +enum +{ + CSC_UPDATECOMMANDS = -1, + CSC_NAVIGATEFORWARD = 1, + CSC_NAVIGATEBACK = 2 +}CommandStateChangeConstants; +enum +{ + OLECMDID_OPEN = 1, + OLECMDID_NEW = 2, + OLECMDID_SAVE = 3, + OLECMDID_SAVEAS = 4, + OLECMDID_SAVECOPYAS = 5, + OLECMDID_PRINT = 6, + OLECMDID_PRINTPREVIEW = 7, + OLECMDID_PAGESETUP = 8, + OLECMDID_SPELL = 9, + OLECMDID_PROPERTIES = 10, + OLECMDID_CUT = 11, + OLECMDID_COPY = 12, + OLECMDID_PASTE = 13, + OLECMDID_PASTESPECIAL = 14, + OLECMDID_UNDO = 15, + OLECMDID_REDO = 16, + OLECMDID_SELECTALL = 17, + OLECMDID_CLEARSELECTION = 18, + OLECMDID_ZOOM = 19, + OLECMDID_GETZOOMRANGE = 20, + OLECMDID_UPDATECOMMANDS = 21, + OLECMDID_REFRESH = 22, + OLECMDID_STOP = 23, + OLECMDID_HIDETOOLBARS = 24, + OLECMDID_SETPROGRESSMAX = 25, + OLECMDID_SETPROGRESSPOS = 26, + OLECMDID_SETPROGRESSTEXT = 27, + OLECMDID_SETTITLE = 28, + OLECMDID_SETDOWNLOADSTATE = 29, + OLECMDID_STOPDOWNLOAD = 30, + OLECMDID_ONTOOLBARACTIVATED = 31, + OLECMDID_FIND = 32, + OLECMDID_DELETE = 33, + OLECMDID_HTTPEQUIV = 34, + OLECMDID_HTTPEQUIV_DONE = 35, + OLECMDID_ENABLE_INTERACTION = 36, + OLECMDID_ONUNLOAD = 37, + OLECMDID_PROPERTYBAG2 = 38, + OLECMDID_PREREFRESH = 39, + OLECMDID_SHOWSCRIPTERROR = 40, + OLECMDID_SHOWMESSAGE = 41, + OLECMDID_SHOWFIND = 42, + OLECMDID_SHOWPAGESETUP = 43, + OLECMDID_SHOWPRINT = 44, + OLECMDID_CLOSE = 45, + OLECMDID_ALLOWUILESSSAVEAS = 46, + OLECMDID_DONTDOWNLOADCSS = 47, + OLECMDID_UPDATEPAGESTATUS = 48, + OLECMDID_PRINT2 = 49, + OLECMDID_PRINTPREVIEW2 = 50, + OLECMDID_SETPRINTTEMPLATE = 51, + OLECMDID_GETPRINTTEMPLATE = 52 +}OLECMDID; +enum +{ + OLECMDF_SUPPORTED = 1, + OLECMDF_ENABLED = 2, + OLECMDF_LATCHED = 4, + OLECMDF_NINCHED = 8, + OLECMDF_INVISIBLE = 16, + OLECMDF_DEFHIDEONCTXTMENU = 32 +}OLECMDF; +enum +{ + OLECMDEXECOPT_DODEFAULT = 0, + OLECMDEXECOPT_PROMPTUSER = 1, + OLECMDEXECOPT_DONTPROMPTUSER = 2, + OLECMDEXECOPT_SHOWHELP = 3 +}OLECMDEXECOPT; +enum +{ + READYSTATE_UNINITIALIZED = 0, + READYSTATE_LOADING = 1, + READYSTATE_LOADED = 2, + READYSTATE_INTERACTIVE = 3, + READYSTATE_COMPLETE = 4 +}tagREADYSTATE; +enum +{ + secureLockIconUnsecure = 0, + secureLockIconMixed = 1, + secureLockIconSecureUnknownBits = 2, + secureLockIconSecure40Bit = 3, + secureLockIconSecure56Bit = 4, + secureLockIconSecureFortezza = 5, + secureLockIconSecure128Bit = 6 +}SecureLockIconConstants; +enum +{ + SWC_EXPLORER = 0, + SWC_BROWSER = 1, + SWC_3RDPARTY = 2, + SWC_CALLBACK = 4 +}ShellWindowTypeConstants; +enum +{ + SWFO_NEEDDISPATCH = 1, + SWFO_INCLUDEPENDING = 2, + SWFO_COOKIEPASSED = 4 +}ShellWindowFindWindowOptions; + + +// Operations +public: + +// IWebBrowser2 + +// Functions +// + +void GoBack() +{ + InvokeHelper(0x64, DISPATCH_METHOD, VT_EMPTY, NULL, NULL); +} +void GoForward() +{ + InvokeHelper(0x65, DISPATCH_METHOD, VT_EMPTY, NULL, NULL); +} +void GoHome() +{ + InvokeHelper(0x66, DISPATCH_METHOD, VT_EMPTY, NULL, NULL); +} +void GoSearch() +{ + InvokeHelper(0x67, DISPATCH_METHOD, VT_EMPTY, NULL, NULL); +} +void Navigate(LPCTSTR URL, VARIANT * Flags, VARIANT * TargetFrameName, VARIANT * PostData, VARIANT * Headers) +{ + static BYTE parms[] = VTS_BSTR VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT ; + InvokeHelper(0x68, DISPATCH_METHOD, VT_EMPTY, NULL, parms, URL, Flags, TargetFrameName, PostData, Headers); +} +void Refresh() +{ + InvokeHelper(DISPID_REFRESH, DISPATCH_METHOD, VT_EMPTY, NULL, NULL); +} +void Refresh2(VARIANT * Level) +{ + static BYTE parms[] = VTS_PVARIANT ; + InvokeHelper(0x69, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Level); +} +void Stop() +{ + InvokeHelper(0x6a, DISPATCH_METHOD, VT_EMPTY, NULL, NULL); +} +LPDISPATCH get_Application() +{ + LPDISPATCH result; + InvokeHelper(0xc8, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL); + return result; +} +LPDISPATCH get_Parent() +{ + LPDISPATCH result; + InvokeHelper(0xc9, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL); + return result; +} +LPDISPATCH get_Container() +{ + LPDISPATCH result; + InvokeHelper(0xca, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL); + return result; +} +LPDISPATCH get_Document() +{ + LPDISPATCH result; + InvokeHelper(0xcb, DISPATCH_PROPERTYGET, VT_DISPATCH, (void*)&result, NULL); + return result; +} +BOOL get_TopLevelContainer() +{ + BOOL result; + InvokeHelper(0xcc, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +CString get_Type() +{ + CString result; + InvokeHelper(0xcd, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL); + return result; +} +long get_Left() +{ + long result; + InvokeHelper(0xce, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL); + return result; +} +void put_Left(long newValue) +{ + static BYTE parms[] = VTS_I4 ; + InvokeHelper(0xce, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +long get_Top() +{ + long result; + InvokeHelper(0xcf, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL); + return result; +} +void put_Top(long newValue) +{ + static BYTE parms[] = VTS_I4 ; + InvokeHelper(0xcf, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +long get_Width() +{ + long result; + InvokeHelper(0xd0, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL); + return result; +} +void put_Width(long newValue) +{ + static BYTE parms[] = VTS_I4 ; + InvokeHelper(0xd0, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +long get_Height() +{ + long result; + InvokeHelper(0xd1, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL); + return result; +} +void put_Height(long newValue) +{ + static BYTE parms[] = VTS_I4 ; + InvokeHelper(0xd1, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +CString get_LocationName() +{ + CString result; + InvokeHelper(0xd2, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL); + return result; +} +CString get_LocationURL() +{ + CString result; + InvokeHelper(0xd3, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL); + return result; +} +BOOL get_Busy() +{ + BOOL result; + InvokeHelper(0xd4, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void Quit() +{ + InvokeHelper(0x12c, DISPATCH_METHOD, VT_EMPTY, NULL, NULL); +} +void ClientToWindow(long * pcx, long * pcy) +{ + static BYTE parms[] = VTS_PI4 VTS_PI4 ; + InvokeHelper(0x12d, DISPATCH_METHOD, VT_EMPTY, NULL, parms, pcx, pcy); +} +void PutProperty(LPCTSTR Property, VARIANT vtValue) +{ + static BYTE parms[] = VTS_BSTR VTS_VARIANT ; + InvokeHelper(0x12e, DISPATCH_METHOD, VT_EMPTY, NULL, parms, Property, &vtValue); +} +VARIANT GetProperty(LPCTSTR Property) +{ + VARIANT result; + static BYTE parms[] = VTS_BSTR ; + InvokeHelper(0x12f, DISPATCH_METHOD, VT_VARIANT, (void*)&result, parms, Property); + return result; +} +CString get_Name() +{ + CString result; + InvokeHelper(0x0, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL); + return result; +} +long get_HWND() +{ + long result; + InvokeHelper(DISPID_HWND, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL); + return result; +} +CString get_FullName() +{ + CString result; + InvokeHelper(0x190, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL); + return result; +} +CString get_Path() +{ + CString result; + InvokeHelper(0x191, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL); + return result; +} +BOOL get_Visible() +{ + BOOL result; + InvokeHelper(0x192, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_Visible(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x192, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +BOOL get_StatusBar() +{ + BOOL result; + InvokeHelper(0x193, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_StatusBar(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x193, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +CString get_StatusText() +{ + CString result; + InvokeHelper(0x194, DISPATCH_PROPERTYGET, VT_BSTR, (void*)&result, NULL); + return result; +} +void put_StatusText(LPCTSTR newValue) +{ + static BYTE parms[] = VTS_BSTR ; + InvokeHelper(0x194, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +long get_ToolBar() +{ + long result; + InvokeHelper(0x195, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL); + return result; +} +void put_ToolBar(long newValue) +{ + static BYTE parms[] = VTS_I4 ; + InvokeHelper(0x195, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +BOOL get_MenuBar() +{ + BOOL result; + InvokeHelper(0x196, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_MenuBar(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x196, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +BOOL get_FullScreen() +{ + BOOL result; + InvokeHelper(0x197, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_FullScreen(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x197, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +void Navigate2(VARIANT * URL, VARIANT * Flags, VARIANT * TargetFrameName, VARIANT * PostData, VARIANT * Headers) +{ + static BYTE parms[] = VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT ; + InvokeHelper(0x1f4, DISPATCH_METHOD, VT_EMPTY, NULL, parms, URL, Flags, TargetFrameName, PostData, Headers); +} +long QueryStatusWB(long cmdID) +{ + long result; + static BYTE parms[] = VTS_I4 ; + InvokeHelper(0x1f5, DISPATCH_METHOD, VT_I4, (void*)&result, parms, cmdID); + return result; +} +void ExecWB(long cmdID, long cmdexecopt, VARIANT * pvaIn, VARIANT * pvaOut) +{ + static BYTE parms[] = VTS_I4 VTS_I4 VTS_PVARIANT VTS_PVARIANT ; + InvokeHelper(0x1f6, DISPATCH_METHOD, VT_EMPTY, NULL, parms, cmdID, cmdexecopt, pvaIn, pvaOut); +} +void ShowBrowserBar(VARIANT * pvaClsid, VARIANT * pvarShow, VARIANT * pvarSize) +{ + static BYTE parms[] = VTS_PVARIANT VTS_PVARIANT VTS_PVARIANT ; + InvokeHelper(0x1f7, DISPATCH_METHOD, VT_EMPTY, NULL, parms, pvaClsid, pvarShow, pvarSize); +} +long get_ReadyState() +{ + long result; + InvokeHelper(DISPID_READYSTATE, DISPATCH_PROPERTYGET, VT_I4, (void*)&result, NULL); + return result; +} +BOOL get_Offline() +{ + BOOL result; + InvokeHelper(0x226, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_Offline(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x226, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +BOOL get_Silent() +{ + BOOL result; + InvokeHelper(0x227, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_Silent(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x227, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +BOOL get_RegisterAsBrowser() +{ + BOOL result; + InvokeHelper(0x228, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_RegisterAsBrowser(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x228, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +BOOL get_RegisterAsDropTarget() +{ + BOOL result; + InvokeHelper(0x229, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_RegisterAsDropTarget(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x229, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +BOOL get_TheaterMode() +{ + BOOL result; + InvokeHelper(0x22a, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_TheaterMode(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x22a, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +BOOL get_AddressBar() +{ + BOOL result; + InvokeHelper(0x22b, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_AddressBar(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x22b, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} +BOOL get_Resizable() +{ + BOOL result; + InvokeHelper(0x22c, DISPATCH_PROPERTYGET, VT_BOOL, (void*)&result, NULL); + return result; +} +void put_Resizable(BOOL newValue) +{ + static BYTE parms[] = VTS_BOOL ; + InvokeHelper(0x22c, DISPATCH_PROPERTYPUT, VT_EMPTY, NULL, parms, newValue); +} + +// Properties +// + + + +}; diff --git a/fcastwin/res/FcastWin.ico b/fcastwin/res/FcastWin.ico new file mode 100644 index 0000000..8a84ca3 Binary files /dev/null and b/fcastwin/res/FcastWin.ico differ diff --git a/fcastwin/res/FcastWin.manifest b/fcastwin/res/FcastWin.manifest new file mode 100644 index 0000000..e325fa8 --- /dev/null +++ b/fcastwin/res/FcastWin.manifest @@ -0,0 +1,22 @@ + + + +Tapez ici une description de votre application + + + + + + diff --git a/fcastwin/res/FcastWin.rc b/fcastwin/res/FcastWin.rc new file mode 100644 index 0000000..f0c5bf2 --- /dev/null +++ b/fcastwin/res/FcastWin.rc @@ -0,0 +1,315 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "afxres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// Français (France) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +#ifdef _WIN32 +LANGUAGE LANG_FRENCH, SUBLANG_FRENCH +#pragma code_page(1252) +#endif //_WIN32 + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""afxres.h""\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "#define _AFX_NO_SPLITTER_RESOURCES\r\n" + "#define _AFX_NO_OLE_RESOURCES\r\n" + "#define _AFX_NO_TRACKER_RESOURCES\r\n" + "#define _AFX_NO_PROPERTY_RESOURCES\r\n" + "\r\n" + "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA)\r\n" + "LANGUAGE 12, 1\r\n" + "#pragma code_page(1252)\r\n" + "#include ""FcastWin.rc2"" // ressources non modifiées par Microsoft Visual C++ \r\n" + "#include ""afxres.rc"" // Composants standard\r\n" + "#endif\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +IDR_MAINFRAME ICON "FcastWin.ico" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +IDD_ABOUTBOX DIALOGEX 0, 0, 247, 243 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | + WS_SYSMENU +CAPTION "À propos de FcastWin" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + ICON IDR_MAINFRAME,IDC_STATIC,107,7,20,20 + CTEXT "FcastWin Multicast File Transfert Tool 1.1\nMultiCast Library (MCL)\n\nmain author/contact: vincent.roca@inrialpes.fr", + IDC_STATIC,34,36,178,49,SS_NOPREFIX + CTEXT "Copyright (c) 1999-2002 INRIA - Univ. Paris 6 - All rights reserved", + IDC_STATIC,16,206,216,8 + DEFPUSHBUTTON "OK",IDOK,104,223,38,13,WS_GROUP + EDITTEXT IDC_EDIT_CREDITS,7,79,233,122,ES_MULTILINE | + ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_READONLY | + WS_VSCROLL +END + +IDD_FCASTWIN_DIALOG DIALOGEX 0, 0, 332, 326 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | WS_MINIMIZEBOX | + WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU +EXSTYLE WS_EX_APPWINDOW +CAPTION "WinFCAST 1.1" +FONT 8, "MS Shell Dlg", 400, 0, 0x0 +BEGIN + CONTROL "",IDC_IEXPLORE,"{8856F961-340A-11D0-A96B-00C04FD705A2}", + WS_TABSTOP,8,21,11,9 + CONTROL "",IDC_TABCTRL,"SysTabControl32",TCS_TOOLTIPS | + WS_TABSTOP,3,1,325,13 + GROUPBOX "",IDC_STATIC,3,9,325,313 + GROUPBOX "Multicast Group (or unicast IP)",IDC_ZONE_ADDR,8,21,203, + 54,0,WS_EX_TRANSPARENT + LTEXT "Address:",IDC_STATIC_ADDR,16,45,29,8,0, + WS_EX_TRANSPARENT + CONTROL "",IDC_IPADDR,"SysIPAddress32",WS_TABSTOP,46,43,99,12 + LTEXT "Port:",IDC_STATIC_PORT,153,45,15,8 + EDITTEXT IDC_PORT,171,43,30,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_NUMBER + GROUPBOX "Output",IDC_ZONE_OUTPUT,217,21,106,54 + RTEXT "Verbosity level [0-5] :",IDC_STATIC_TRACELVL,222,31,70, + 8 + EDITTEXT IDC_EDIT_TRACELVL,293,29,14,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_NUMBER + RTEXT "Statistic level [0-2] :",IDC_STATIC_STATLVL,226,46,66,8 + EDITTEXT IDC_EDIT_STATLVL,293,44,14,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "Silent mode",IDC_CHECK_SILENT,"Button",BS_AUTOCHECKBOX | + WS_TABSTOP,237,60,53,10 + GROUPBOX "File(s) to send",IDC_ZONE_PATH,8,79,315,49 + LTEXT "Path:",IDC_STATIC_PATH,24,94,16,8 + EDITTEXT IDC_EDIT_PATH_SEND,44,93,182,12,ES_AUTOHSCROLL + PUSHBUTTON "Browse",IDC_BUTTON_BROWSE,229,92,28,13 + CONTROL "Directory send (recursive)",IDC_CHECK_RECURSIVE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,42,110,135,10 + CONTROL "Set number of layers to",IDC_CHECK_NLAYER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,144,88,10 + EDITTEXT IDC_EDIT_NLVL,108,143,14,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "Enable demux. LCT TSI value:",IDC_CHECK_DEMUX,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,173,112,10 + EDITTEXT IDC_EDIT_TSI,130,172,31,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_NUMBER + LTEXT "Temp Directory :",IDC_STATIC_TMPDIR,25,190,54,8 + EDITTEXT IDC_EDIT_TMPDIR,79,188,82,14,ES_AUTOHSCROLL + LTEXT "Profile:",IDC_STATIC_PROFILE,191,144,24,8 + COMBOBOX IDC_COMBO_PROFILE,218,141,66,29,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Optimization:",IDC_STATIC_OPTIMIZE,191,179,41,8 + COMBOBOX IDC_COMBO_OPTIMIZE,236,177,47,30,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + LTEXT "Interface:",IDC_STATIC_IF,191,194,34,8 + COMBOBOX IDC_COMBO_IF,228,192,71,25,CBS_DROPDOWN | CBS_SORT | + WS_DISABLED | WS_VSCROLL | WS_TABSTOP + GROUPBOX "Options",IDC_ZONE_OPT,8,133,315,138 + CONTROL "Set packets TTL to",IDC_CHECK_TTL,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,213,71,10 + EDITTEXT IDC_EDIT_TTL,91,211,21,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "Continuous delivery mode (""On demand"")", + IDC_CHECK_CONT,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,17, + 232,148,10 + CONTROL "Repeat mode : send",IDC_CHECK_REPEAT,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,251,76,10 + EDITTEXT IDC_EDIT_NREPEAT,97,250,21,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_NUMBER + LTEXT "times",IDC_STATIC_REPEAT,123,252,18,9 + CONTROL "Set FEC Ratio to:",IDC_CHECK_FEC,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,191,214,69,10 + EDITTEXT IDC_EDIT_FEC,261,212,16,12,ES_RIGHT | ES_AUTOHSCROLL | + ES_NUMBER + CONTROL "Huge files mode",IDC_CHECK_HUGE,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,191,232,67,10 + DEFPUSHBUTTON "Send or Receive",IDC_START,263,300,62,19 + GROUPBOX "Options",IDC_ZONE_OPTRCV,8,133,315,75 + EDITTEXT IDC_EDIT_CMDLINE,55,278,238,13,ES_AUTOHSCROLL + PUSHBUTTON "Update",IDC_BTN_UPDATE,295,278,30,12 + LTEXT "Fcast params:",IDC_STATIC_CMDLINE,7,280,46,8 + EDITTEXT IDC_EDIT_PATH_RECV,41,93,185,12,ES_AUTOHSCROLL + LTEXT "Overwrite existing files:",IDC_STATIC_OVERWRITE,24,111, + 77,8 + COMBOBOX IDC_COMBO_OVERWRITE,101,108,40,30,CBS_DROPDOWNLIST | + CBS_SORT | WS_VSCROLL | WS_TABSTOP + EDITTEXT IDC_EDIT_STATUS,5,298,256,21,ES_MULTILINE | ES_READONLY | + NOT WS_BORDER + EDITTEXT IDC_EDIT_DSIZE,227,157,23,14,ES_AUTOHSCROLL | ES_NUMBER + EDITTEXT IDC_EDIT_BW,294,157,25,14,ES_AUTOHSCROLL | ES_NUMBER + LTEXT "Bandwidth:",IDC_STATIC_BW,258,159,35,8 + LTEXT "Datagram size:",IDC_STATIC_DSIZE,191,155,32,15,0, + WS_EX_RIGHT + CONTROL "single layer mode",IDC_CHECK_SINGLELAYER,"Button", + BS_AUTOCHECKBOX | WS_TABSTOP,17,158,88,10 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 1,0,0,1 + PRODUCTVERSION 1,0,0,1 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040c04e4" + BEGIN + VALUE "CompanyName", "TODO: " + VALUE "FileDescription", "TODO: " + VALUE "FileVersion", "1.0.0.1" + VALUE "InternalName", "FcastWin.exe" + VALUE "LegalCopyright", "TODO: (c) . Tous droits réservés." + VALUE "OriginalFilename", "FcastWin.exe" + VALUE "ProductName", "TODO: " + VALUE "ProductVersion", "1.0.0.1" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x40c, 1252 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + IDD_ABOUTBOX, DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 240 + TOPMARGIN, 7 + BOTTOMMARGIN, 236 + END + + IDD_FCASTWIN_DIALOG, DIALOG + BEGIN + LEFTMARGIN, 3 + RIGHTMARGIN, 328 + TOPMARGIN, 1 + BOTTOMMARGIN, 322 + END +END +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// RT_MANIFEST +// + +IDR_MANIFEST RT_MANIFEST "FcastWin.manifest" + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog Info +// + +IDD_FCASTWIN_DIALOG DLGINIT +BEGIN + IDC_IEXPLORE, 0x376, 160, 0 +0x0000, 0x0000, 0x004c, 0x0000, 0x01c2, 0x0000, 0x018d, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x004c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, +0x0000, 0xd0e0, 0x0057, 0x3573, 0x11cf, 0x69ae, 0x0008, 0x2e2b, 0x6212, +0x0008, 0x0000, 0x0000, 0x0000, 0x004c, 0x0000, 0x1401, 0x0002, 0x0000, +0x0000, 0x00c0, 0x0000, 0x0000, 0x4600, 0x0080, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0000, +0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0 +END + + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_ABOUTBOX "&À propos de FcastWin..." +END + +#endif // Français (France) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// +#define _AFX_NO_SPLITTER_RESOURCES +#define _AFX_NO_OLE_RESOURCES +#define _AFX_NO_TRACKER_RESOURCES +#define _AFX_NO_PROPERTY_RESOURCES + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_FRA) +LANGUAGE 12, 1 +#pragma code_page(1252) +#include "FcastWin.rc2" // ressources non modifiées par Microsoft Visual C++ +#include "afxres.rc" // Composants standard +#endif + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/fcastwin/res/FcastWin.rc2 b/fcastwin/res/FcastWin.rc2 new file mode 100644 index 0000000..32f55b1 --- /dev/null +++ b/fcastwin/res/FcastWin.rc2 @@ -0,0 +1,13 @@ +// +// Ressources FcastWin.RC2 non modifiées directement par Microsoft Visual C++ +// + +#ifdef APSTUDIO_INVOKED +#error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Ajoutez ici les ressources modifiées manuellement... + +///////////////////////////////////////////////////////////////////////////// diff --git a/fcastwin/res/resource.h b/fcastwin/res/resource.h new file mode 100644 index 0000000..6b74441 --- /dev/null +++ b/fcastwin/res/resource.h @@ -0,0 +1,82 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by FcastWin.rc +// +#define IDR_MANIFEST 1 +#define IDM_ABOUTBOX 0x0010 +#define IDD_ABOUTBOX 100 +#define IDS_ABOUTBOX 101 +#define IDD_FCASTWIN_DIALOG 102 +#define IDR_MAINFRAME 128 +#define IDC_RICHEDIT_STATUS 1000 +#define IDC_START 1002 +#define IDC_TABCTRL 1005 +#define IDC_IPADDR 1006 +#define IDC_PORT 1011 +#define IDC_CHECK_CONT 1015 +#define IDC_CHECK_REPEAT 1016 +#define IDC_EDIT_NREPEAT 1017 +#define IDC_INTERFACE 1018 +#define IDC_COMBO_IF 1018 +#define IDC_EDIT_NLVL 1019 +#define IDC_EDIT_TSI 1020 +#define IDC_EDIT_TRACELVL 1021 +#define IDC_EDIT_STATLVL 1022 +#define IDC_CHECK_SILENT 1023 +#define IDC_EDIT_TMPDIR 1024 +#define IDC_EDIT_TTL 1025 +#define IDC_EDIT_FEC 1027 +#define IDC_CHECK_HUGE 1028 +#define IDC_CHECK_DEMUX 1030 +#define IDC_CHECK_FEC 1033 +#define IDC_CHECK_TTL 1034 +#define IDC_CHECK_NLAYER 1037 +#define IDC_ZONE_OPT 1038 +#define IDC_EDIT_PATH 1039 +#define IDC_EDIT_PATH_SEND 1039 +#define IDC_BUTTON_BROWSE 1040 +#define IDC_COMBO_PROFILE 1041 +#define IDC_ZONE_PATH 1042 +#define IDC_COMBO_OPTIMIZE 1043 +#define IDC_ZONE_ADDR 1044 +#define IDC_STATIC_ADDR 1045 +#define IDC_STATIC_PORT 1046 +#define IDC_CHECK_RECURSIVE 1047 +#define IDC_STATIC_PATH 1048 +#define IDC_CHECK_OVERWRITE 1049 +#define IDC_COMBO_OVERWRITE 1049 +#define IDC_STATIC_PROFILE 1050 +#define IDC_STATIC_OPTIMIZE 1051 +#define IDC_STATIC_REPEAT 1052 +#define IDC_ZONE_OPTRCV 1053 +#define IDC_ZONE_OUTPUT 1054 +#define IDC_STATIC_TRACELVL 1055 +#define IDC_STATIC_STATLVL 1056 +#define IDC_STATIC_TMPDIR 1057 +#define IDC_STATIC_IF 1058 +#define IDC_EDIT_PATH_RECV 1059 +#define IDC_CHECK_NLAYER2 1060 +#define IDC_CHECK_SINGLELAYER 1060 +#define IDC_EXPLORER1 1063 +#define IDC_IEXPLORE 1063 +#define IDC_BTN_UPDATE 1064 +#define IDC_EDIT_CREDITS 1066 +#define IDC_EDIT_CMDLINE 1067 +#define IDC_STATIC_OVERWRITE 1070 +#define IDC_EDIT_STATUS 1072 +#define IDC_STATIC_CMDLINE 1073 +#define IDC_EDIT_DSIZE 1074 +#define IDC_EDIT_BW 1075 +#define IDC_STATIC_BW 1076 +#define IDC_STATIC_DSIZE 1077 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 131 +#define _APS_NEXT_COMMAND_VALUE 32771 +#define _APS_NEXT_CONTROL_VALUE 1074 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/fcastwin/stdafx.cpp b/fcastwin/stdafx.cpp new file mode 100644 index 0000000..85ec188 --- /dev/null +++ b/fcastwin/stdafx.cpp @@ -0,0 +1,7 @@ +// stdafx.cpp : le fichier source qui inclut uniquement le fichier Include +// FcastWin.pch sera l'en-tête précompilé +// stdafx.obj contiendra les informations de type précompilé + +#include "stdafx.h" + + diff --git a/fcastwin/stdafx.h b/fcastwin/stdafx.h new file mode 100644 index 0000000..0b75c1e --- /dev/null +++ b/fcastwin/stdafx.h @@ -0,0 +1,42 @@ +// stdafx.h : fichier Include pour les fichiers Include système standard, +// ou pour les fichiers Include spécifiques au projet qui sont fréquemment utilisés, +// mais rarement modifiés + +#pragma once + +#ifndef VC_EXTRALEAN +#define VC_EXTRALEAN // Exclut les informations rarement utilisées des en-têtes Windows +#endif + +// Modifiez les valeurs suivantes si votre plate-forme cible est antérieure aux plates-formes spécifiées ci-après. +// Consultez la documentation MSDN pour obtenir des informations récentes sur les valeurs respectives des différentes plates-formes. +#ifndef WINVER // Permet l'utilisation de fonctionnalités spécifiques à Windows 95 et à Windows NT 4 ou version ultérieure. +#define WINVER 0x0400 // La valeur appropriée doit être utilisée pour des applications cibles Windows 98 et Windows 2000 ou version ultérieure. +#endif + +#ifndef _WIN32_WINNT // Permet l'utilisation de fonctionnalités spécifiques à Windows NT 4 ou version ultérieure. +#define _WIN32_WINNT 0x0400 // La valeur appropriée doit être utilisée pour des applications cibles Windows 98 et Windows 2000 ou version ultérieure. +#endif + +#ifndef _WIN32_WINDOWS // Permet l'utilisation de fonctionnalités spécifiques à Windows 98 ou version ultérieure. +#define _WIN32_WINDOWS 0x0410 // La valeur appropriée doit être utilisée pour des applications cibles Windows Me ou version ultérieure. +#endif + +#ifndef _WIN32_IE // Permet l'utilisation de fonctionnalités spécifiques à Internet Explorer 4.0 ou version ultérieure. +#define _WIN32_IE 0x0400 // La valeur appropriée doit être utilisée pour des applications cibles Internet Explorer 5.0 ou version ultérieure. +#endif + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // certains constructeurs CString seront explicites + +// désactive le masquage MFC de certains messages d'avertissement courants et par ailleurs souvent ignorés +#define _AFX_ALL_WARNINGS + +#include // composants MFC principaux et standard +#include // extensions MFC +#include // classes Automation MFC + +#include // Prise en charge MFC des contrôles communs Internet Explorer 4 +#ifndef _AFX_NO_AFXCMN_SUPPORT +#include // Prise en charge MFC des contrôles communs Windows +#endif // _AFX_NO_AFXCMN_SUPPORT + diff --git a/flute/Makefile b/flute/Makefile new file mode 100644 index 0000000..dde48df --- /dev/null +++ b/flute/Makefile @@ -0,0 +1,186 @@ + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Makefile.common + + +# libraries required +ifeq (${OS},linux) + # Linux version + # + BINDIR = ../bin/linux + LDPC_BINDIR = ../../ldpc/bin/linux + XERCES_DIR = ../../xerces-c + # Shared version (default) + LIBRARIES = -lc -lm -lpthread + #-lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},solaris) + # Solaris version: + # Warning: SUN recommends to have -lucb at the end of list, + # in order to priviledge SUN's libs to the BSD compatibility + # lib (libucb). + # CC requires: -mt -lpthread for multithreaded applications + # OpenSSL is installed at /usr/local/ssl in our system. Update if + # needed. + # + BINDIR = ../bin/solaris + LDPC_BINDIR = ../../ldpc/bin/solaris + XERCES_DIR = ../../xerces-c + OPENSSL_DIR = /usr/local/ssl + LIBRARIES = -lc -lm -lsocket -lnsl -lposix4 -mt -lpthread -L/usr/ucblib -lucb -L${OPENSSL_DIR}/lib -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include -I${OPENSSL_DIR}/include +endif + +ifeq (${OS},freebsd) + # FreeBSD version: + # CC requires: -mt -lpthread for multithreaded applications + # + BINDIR = ../bin/freebsd + LDPC_BINDIR = ../../ldpc/bin/freebsd + XERCES_DIR = ../../xerces-c + LIBRARIES = -lm -pthread -L/usr/local/lib -lcrypto + #ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include + ADD_INCLUDES = -I${XERCES_DIR}/include +endif + +ifeq (${OS},aix) + # AIX version + BINDIR = ../bin/aix + LDPC_BINDIR = ../../ldpc/bin/aix + XERCES_DIR = ../../xerces-c + LIBRARIES = -lm -pthread -lc -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},hp-ux) + # HP-UX version + BINDIR = ../bin/hp-ux + LDPC_BINDIR = ../../ldpc/bin/hp-ux + XERCES_DIR = ../../xerces-c + LIBRARIES = -lc -lm -pthread -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},irix) + # IRIX version + BINDIR = ../bin/irix + LDPC_BINDIR = ../../ldpc/bin/irix + XERCES_DIR = ../../xerces-c + LIBRARIES = -lc -lm -pthread -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + + +###### Other variables ###### +# Local CFLAGS. + +# gcc version +#CFLAGS = -g -pg -O ${OSFLAGS} -DALC ${ADD_INCLUDES} +CFLAGS = -g -O -DDEBUG ${OSFLAGS} -DALC ${ADD_INCLUDES} +#CFLAGS = -O ${OSFLAGS} -DALC ${ADD_INCLUDES} +#static: CFLAGS := ${CFLAGS} -static -static-libgcc + +# add purify linker for memory debug (Solaris only). +# Purify 4.0 Solaris 2, Copyright (C) 1992-1996 Pure Software Inc. +# +#CCLINK_PURE = purify $(CC) +CCLINK_PURE = purify -cache-dir=/tmp $(CC) + +# add quantify linker for profiling (Solaris only). +CCLINK_QUANTIFY = quantify $(CC) + +# list of source and object files +SRCFILES = main.cpp fsend.cpp frecv.cpp getopt.cpp display.cpp file_tools.cpp +OFILES = ${SRCFILES:.cpp=.o} + +#OS flag with upper case chars +OS_UPPER_CASE = `echo ${OS} | tr 'a-z' 'A-Z'` + + +# XML parsing library +# choose between the static / dynamic (default) xerces-c versions. +dynamic: LIBRARIES := ${LIBRARIES} -lxerces-c -lxerces-depdom +static: LIBRARIES := ${LIBRARIES} ${XERCES_DIR}/lib/libxerces-c.a + +# Other libraries +MCL_LIBRARY = ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +SDP_LIBRARY = ${BINDIR}/libsinistersdp.a +FLUTE_LIBRARY = ${BINDIR}/libflute.a + +# executable is here: +dynamic: TARGET_FLUTE = ${BINDIR}/flute +static: TARGET_FLUTE = ${BINDIR}/flute-static + + +###### Dependancies ###### + +# by default, build the dynamic FLUTE version... +all: dynamic + + +# Rule for C++ .cpp extension +.cpp.o: + $(CC) -c $(CFLAGS) -o $*.o $*.cpp + +dynamic: ${OFILES} ${FLUTE_LIBRARY} + @echo "** Compiling flute-ALC using the MCL library..." + ${CC} ${CFLAGS} ${OFILES} ${LIBRARIES} ${FLUTE_LIBRARY} ${SDP_LIBRARY} ${MCL_LIBRARY} -o ${TARGET_FLUTE} + + +static: ${OFILES} ${FLUTE_LIBRARY} + @echo "** Compiling flute-ALC using the MCL library..." + ${CC} -static -static-libgcc ${CFLAGS} ${OFILES} ${FLUTE_LIBRARY} ${SDP_LIBRARY} ${MCL_LIBRARY} ${LIBRARIES} -o ${TARGET_FLUTE} + +clean : + @for f in core ${OFILES} *_pure* *.pure_* .pur* *purify* ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in ${BINDIR}/flute ${BINDIR}/flute-static; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +main.o: ../src/flute_lib/FluteAPI.h ../src/common/mcl_lib_api.h +main.o: ../src/common/mcl_types.h ../src/alc/mcl_lib_api_alc.h +main.o: ../src/flute_lib/Flute.h ../src/flute_lib/FluteReceiver.h +main.o: ../src/flute_lib/FluteSender.h ../src/flute_lib/FluteFileInfo.h +main.o: ../src/flute_lib/FluteFileDeliveryCarousel.h fsend.h frecv.h +main.o: display.h macros.h +fsend.o: ../src/flute_lib/FluteAPI.h ../src/common/mcl_lib_api.h +fsend.o: ../src/common/mcl_types.h ../src/alc/mcl_lib_api_alc.h +fsend.o: ../src/flute_lib/Flute.h ../src/flute_lib/FluteReceiver.h +fsend.o: ../src/flute_lib/FluteSender.h ../src/flute_lib/FluteFileInfo.h +fsend.o: ../src/flute_lib/FluteFileDeliveryCarousel.h fsend.h file_tools.h +fsend.o: macros.h +frecv.o: ../src/flute_lib/FluteAPI.h ../src/common/mcl_lib_api.h +frecv.o: ../src/common/mcl_types.h ../src/alc/mcl_lib_api_alc.h +frecv.o: ../src/flute_lib/Flute.h ../src/flute_lib/FluteReceiver.h +frecv.o: ../src/flute_lib/FluteSender.h ../src/flute_lib/FluteFileInfo.h +frecv.o: ../src/flute_lib/FluteFileDeliveryCarousel.h frecv.h macros.h +getopt.o: getopt.h +display.o: ../src/flute_lib/FluteAPI.h ../src/common/mcl_lib_api.h +display.o: ../src/common/mcl_types.h ../src/alc/mcl_lib_api_alc.h +display.o: ../src/flute_lib/Flute.h ../src/flute_lib/FluteReceiver.h +display.o: ../src/flute_lib/FluteSender.h ../src/flute_lib/FluteFileInfo.h +display.o: ../src/flute_lib/FluteFileDeliveryCarousel.h display.h macros.h +file_tools.o: macros.h diff --git a/flute/Makefile.org b/flute/Makefile.org new file mode 100644 index 0000000..7de1c79 --- /dev/null +++ b/flute/Makefile.org @@ -0,0 +1,194 @@ +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Makefile.common + + +# libraries required +ifeq (${OS},linux) + # Linux version + # add MPATROL support if required + # + BINDIR = ../bin/linux + LDPC_BINDIR = ../../ldpc/bin/linux + XERCES_DIR = ../../xerces-c + # Static version, usefull to avoid that clients have to + # install libgdome2 on their host + #LIBRARIES = -lc -lm -lpthread -lglib -lgdome -lxml2 -lssl -static + # Shared version (default) + LIBRARIES = -lc -lm -lpthread -lssl + # added -I/usr/local/include for libgdome header files + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},solaris) + # Solaris version: + # Warning: SUN recommends to have -lucb at the end of list, + # in order to priviledge SUN's libs to the BSD compatibility + # lib (libucb). + # CC requires: -mt -lpthread for multithreaded applications + # + BINDIR = ../bin/solaris + LDPC_BINDIR = ../../ldpc/bin/solaris + XERCES_DIR = ../../xerces-c + LIBRARIES = -lc -lm -lsocket -lnsl -lposix4 -mt -lpthread -L/usr/ucblib -lucb + ADD_INCLUDES = -I/usr/local/include/ +endif + +ifeq (${OS},freebsd) + # FreeBSD version: + # CC requires: -mt -lpthread for multithreaded applications + # + BINDIR = ../bin/freebsd + LDPC_BINDIR = ../../ldpc/bin/freebsd + XERCES_DIR = ../../xerces-c + LIBRARIES = -lm -pthread -L/usr/local/lib + # added -I/usr/local/include for libgdome header files + ADD_INCLUDES = -I/usr/local/include/ +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +#CFLAGS = -g -pg -O ${OSFLAGS} -D${RM_PROTOCOL} ${ADD_INCLUDES} +#CFLAGS = -g -O -DDEBUG ${OSFLAGS} -D${RM_PROTOCOL} ${ADD_INCLUDES} +CFLAGS = -O ${OSFLAGS} -D${RM_PROTOCOL} ${ADD_INCLUDES} + +# add purify linker for memory debug (Solaris only). +# Purify 4.0 Solaris 2, Copyright (C) 1992-1996 Pure Software Inc. +# +#CCLINK_PURE = purify $(CC) +CCLINK_PURE = purify -cache-dir=/tmp $(CC) + +# add quantify linker for profiling (Solaris only). +CCLINK_QUANTIFY = quantify $(CC) + +# list of source and object files +SRCFILES = fdt.cpp filemanage.cpp flute.cpp fsend.cpp frecv.cpp display.cpp flute_md5.cpp flute_lock.cpp +OFILES = ${SRCFILES:.cpp=.o} + +###### choose between the static / dynamic (default) versions ###### + +dynamic: LIBRARIES := ${LIBRARIES} -lxerces-c + +###### ALC ###### + +# Compile either with ALC or NORM support. +# The RM_PROTOCOL and MCL_LIBRARY variables are target-specific. +# In case of ALC, you may have to add libldpc.a depending on what +# FEC codec is used by MCL +RM_PROTOCOL = ALC + +# Edit the following two lines as appropriate, according to the FEC +# codec in use: if LDPC is used, then add the libbdpc.a library. +# If only RSE is used and if you don't have the LDPC archive, then +# remove the libbdpc.a library. +MCL_LIBRARY = ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +XERCES_LIBRARY = ${XERCES_DIR}/lib/libxerces-c.a +TARGET_FLUTE = ${BINDIR}/flute + + +###### Dependancies ###### + +all: dynamic + +#${TARGET_FLUTE}: ${OFILES} ${MCL_LIBRARY} + +# Rule for C++ .cpp extension +.cpp.o: + $(CC) -c $(CFLAGS) -o $*.o $*.cpp + +dynamic: ${OFILES} ${MCL_LIBRARY} + @echo "** Compiling flute-ALC using the MCL library..." + ${CC} ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} -o ${TARGET_FLUTE} + + +static: ${OFILES} ${MCL_LIBRARY} + @echo "** Compiling flute-ALC using the MCL library..." + @for f in ${XERCES_DIR}/lib/libxerces-c.a; do \ + if [ -f "$${f}" ] ; then \ + echo "libxerces-c.a already exists"; \ + else \ + ${AR} -rcsv ${XERCES_DIR}/lib/libxerces-c.a ${XERCES_DIR}/obj/${OS}/*.o; \ + ${RANLIB} ${XERCES_DIR}/lib/libxerces-c.a; \ + fi \ + done + ${CC} ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} ${XERCES_LIBRARY} -o ${TARGET_FLUTE} + + +#pure: ${OFILES} ${MCL_LIBRARY} +# @echo "** Compiling flute using the MCL library..." +# ${CCLINK_PURE} ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} -o ${TARGET_FLUTE} + +#quantify: ${OFILES} ${MCL_LIBRARY} +# @echo "** Compiling flute using the MCL library..." +# ${CCLINK_QUANTIFY} ${CFLAGS} ${OFILES} ${LIBRARIES} ${MCL_LIBRARY} -o ${TARGET_FLUTE} + +clean : + @for f in core ${OFILES} *_pure* *.pure_* .pur* *purify* ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall_alc : clean + @for f in ${BINDIR}/flute; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + + +cleanall_norm : clean + @for f in ${BINDIR}/fluten; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + + +cleanall : clean + @for f in ${BINDIR}/flute ${BINDIR}/fluten; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +fdt.o: flute.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +fdt.o: ../src/alc/mcl_lib_api_alc.h macros.h filemanage.h flute_md5.h fsend.h +fdt.o: frecv.h fdt.h display.h flute_lock.h +filemanage.o: flute.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +filemanage.o: ../src/alc/mcl_lib_api_alc.h macros.h filemanage.h flute_md5.h +filemanage.o: fsend.h frecv.h fdt.h display.h flute_lock.h +flute.o: flute.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +flute.o: ../src/alc/mcl_lib_api_alc.h macros.h filemanage.h flute_md5.h +flute.o: fsend.h frecv.h fdt.h display.h flute_lock.h +fsend.o: flute.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +fsend.o: ../src/alc/mcl_lib_api_alc.h macros.h filemanage.h flute_md5.h +fsend.o: fsend.h frecv.h fdt.h display.h flute_lock.h +frecv.o: flute.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +frecv.o: ../src/alc/mcl_lib_api_alc.h macros.h filemanage.h flute_md5.h +frecv.o: fsend.h frecv.h fdt.h display.h flute_lock.h +display.o: flute.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +display.o: ../src/alc/mcl_lib_api_alc.h macros.h filemanage.h flute_md5.h +display.o: fsend.h frecv.h fdt.h display.h flute_lock.h +flute_md5.o: flute.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +flute_md5.o: ../src/alc/mcl_lib_api_alc.h macros.h filemanage.h flute_md5.h +flute_md5.o: fsend.h frecv.h fdt.h display.h flute_lock.h +flute_lock.o: flute.h ../src/common/mcl_lib_api.h ../src/common/mcl_types.h +flute_lock.o: ../src/alc/mcl_lib_api_alc.h macros.h filemanage.h flute_md5.h +flute_lock.o: fsend.h frecv.h fdt.h display.h flute_lock.h diff --git a/flute/display.cpp b/flute/display.cpp new file mode 100644 index 0000000..d8fef8a --- /dev/null +++ b/flute/display.cpp @@ -0,0 +1,288 @@ +/* $Id: display.cpp,v 1.9 2005/05/17 13:31:36 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "../src/flute_lib/FluteAPI.h" +#include "display.h" +#include "macros.h" + +extern class Flute *myflute; +extern bool interactive ; + +#ifndef WIN32 +static struct termios initial_settings; + +static void reset_term(void) +{ + tcsetattr(0, TCSANOW, &initial_settings); +} + +static void sig_catcher (int sig) +{ + reset_term(); +} +#endif + +#ifdef WIN32 +void *display_callback(class FluteFileInfo* fileinfolist); +#endif + +void *display(void * arg) +{ + + int interval; + interval = 1; /* Default update rate is 1 seconds */ + +#ifndef WIN32 + struct termios new_settings; + struct sigaction sa; + fd_set readfds; + unsigned char c; + struct timeval tv; + + + unsigned int highlight=0; + TOI_t toi; + + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); + pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS,NULL); + + tcgetattr(0, &initial_settings); + memcpy(&new_settings, &initial_settings, sizeof(struct termios)); + new_settings.c_lflag &= ~(ISIG | ICANON); /* unbuffered input */ + + /* Turn off echoing */ + new_settings.c_lflag &= ~(ECHO | ECHONL); + signal (SIGTERM, sig_catcher); + sigaction (SIGTERM, (struct sigaction *) 0, &sa); + sa.sa_flags |= SA_RESTART; +#if defined(FREEBSD) || defined(SOLARIS) + sa.sa_flags &= ~SA_NOCLDSTOP; +#else + sa.sa_flags &= ~SA_INTERRUPT; +#endif + sigaction (SIGTERM, &sa, (struct sigaction *) 0); + sigaction (SIGINT, &sa, (struct sigaction *) 0); + tcsetattr(0, TCSANOW, &new_settings); + atexit(reset_term); + + while(1) + { + + tv.tv_sec = interval; + tv.tv_usec = 0; + + toi = displayFiles(highlight); + FD_ZERO (&readfds); + FD_SET (0, &readfds); + select (1, &readfds, NULL, NULL, &tv); + if (FD_ISSET (0, &readfds)) { + if (read (0, &c, 1) <= 0) { /* signal */ + EXIT(("Keyboard input error\n")); + } + switch(c) { + case 113: + myflute->abort(); + EXIT(("Good Bye\n")); /**q**/ + break; + case 27: /**arrow pad**/ + if (read (0, &c, 1) <= 0) { /* signal */ + EXIT(("Keyboard input error\n")); + } + if (read (0, &c, 1) <= 0) { /* signal */ + EXIT(("Keyboard input error\n")); + } + if (c==66) highlight++; + if (c==65 && highlight!=0) highlight--; + break; + + case 10: /**ENTER**/ + if (interactive != false) break; + if (toi != 0 && myflute->isSender() == true) ((class FluteReceiver *)myflute)->selectTOI(toi); + + //else FFileRemoveTOI(toi,&myfiles); /deselection not supported yet + break; + } + } + } + +#else /* WIN32 */ + + ((class FluteReceiver *)myflute)->setCallbackReceivedNewFileDescription(display_callback); + + + while (1) + { + Sleep(interval*1000); + } + +#endif + return NULL; +} + + +#ifndef WIN32 +/** + * Displays the FDT on stdout. + * @param highlight index of line highlighted in the File list. + * @return TOI of the highligted line. + */ +TOI_t displayFiles(unsigned int highlight) +{ + + class FluteFileInfo* fileinfolist = NULL; + class FluteFileInfo* fileinfo; + TOI_t returntoi = 0; + int j; + + fileinfolist = myflute->getFileInfoList(); + + /*clear screen*/ + if (myflute->getVerbosity() == 0) printf("\e[H\e[J"); + + if (fileinfolist == NULL) { + printf("FDT is empty\n"); + goto exit; + } + + printf("TOI\tSelect\tRcvd\tLength\tMD5sum\tContent-Location\n\n"); + + /* + * Now go through all entries in the file list... + */ + fileinfo = fileinfolist; + j = 0; + while (fileinfo != NULL) + { + + if (j == highlight) + printf("\e[7m"); + + printf(" %lu\t", fileinfo->getTOI()); + + if (fileinfo->isSelected() == true) { + /* yes, this file is expected! */ + printf("X\t"); + double val; /* percentage */ + val = (double)fileinfo->getBytesRcvd() / (double)fileinfo->getTransferLength() * 100.0; + printf("%.1f\%\t", val); + } else { + printf("\t"); + } + + if (fileinfo->getContentLength() == 0) + printf("?\t"); + else if(fileinfo->getContentLength() < 0) + printf("NOK\t"); + else + printf("%lu\t", fileinfo->getContentLength()); + + if (fileinfo->getIntegrity() == 1) + printf("OK\t"); + else if (fileinfo->getIntegrity() == -1) + printf(" NOK \t"); + else + printf("?\t"); + + char* filename; + int len; + fileinfo->getFilename(&filename,&len); + printf("%s ",filename); + printf("\n"); + + if (j == highlight) { + printf("\e[0m"); + returntoi = fileinfo->getTOI(); + } + + j++; + fileinfo = fileinfo->getNextFile(); + } + +exit: + return returntoi; +} +#endif + + +#ifdef WIN32 +void *display_callback(class FluteFileInfo* fileinfolist) { + + int j; + class FluteFileInfo* fileinfo; + + if (fileinfolist == NULL) { + printf("FDT is empty\n"); + goto exit; + } + + printf("TOI\tSelect\tRcvd\tLength\tMD5sum\tContent-Location\n\n"); + + /* + * Now go through all entries in the file list... + */ + fileinfo = fileinfolist; + j = 0; + while (fileinfo != NULL) + { + printf(" %lu\t", fileinfo->getTOI()); + + if (fileinfo->isSelected() == true) { + /* yes, this file is expected! */ + printf("X\t"); + double val; /* percentage */ + val = (double)fileinfo->getBytesRcvd() / (double)fileinfo->getTransferLength() * 100.0; + printf("%.1f\%\t", val); + } else { + printf("\t"); + } + + if (fileinfo->getContentLength() == 0) + printf("?\t"); + else if(fileinfo->getContentLength() < 0) + printf("NOK\t"); + else + printf("%lu\t", fileinfo->getContentLength()); + + if (fileinfo->getIntegrity() == 1) + printf("OK\t"); + else if (fileinfo->getIntegrity() == -1) + printf(" NOK \t"); + else + printf("?\t"); + + char* filename; + int len; + fileinfo->getFilename(&filename,&len); + printf("%s ",filename); + printf("\n"); + + j++; + fileinfo = fileinfo->getNextFile(); + } + +exit: + + return NULL; +} +#endif + diff --git a/flute/display.h b/flute/display.h new file mode 100644 index 0000000..cf784d3 --- /dev/null +++ b/flute/display.h @@ -0,0 +1,35 @@ +/* $Id: display.h,v 1.5 2005/05/12 16:03:23 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include +#include +#include +#include +#include +#include + + + +void *display(void* arg); +TOI_t displayFiles(unsigned int highlight); diff --git a/flute/fdt.o b/flute/fdt.o new file mode 100644 index 0000000..b6a21b3 Binary files /dev/null and b/flute/fdt.o differ diff --git a/flute/file_tools.cpp b/flute/file_tools.cpp new file mode 100644 index 0000000..3ee42b0 --- /dev/null +++ b/flute/file_tools.cpp @@ -0,0 +1,49 @@ +/* $Id: file_tools.cpp,v 1.2 2005/05/12 16:03:23 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "macros.h" + +int FileExist( const char *filepath) +{ + FILE *check; + check = fopen(filepath, "r"); + + ASSERT(filepath!=NULL); + + if( check == NULL) + return 0; + else + { + fclose(check); + return 1; + } + +} + + +int IsDirDots (const char *path) +{ + return (path[0] == '\0' + || (path[0] == '.' && (path[1] == '\0' + || (path[1] == '.' && path[2] == '\0')))); +} diff --git a/flute/file_tools.h b/flute/file_tools.h new file mode 100644 index 0000000..6725013 --- /dev/null +++ b/flute/file_tools.h @@ -0,0 +1,25 @@ +/* $Id: file_tools.h,v 1.2 2005/05/12 16:03:24 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + int FileExist( const char *filepath); + int IsDirDots (const char *path); diff --git a/flute/filemanage.o b/flute/filemanage.o new file mode 100644 index 0000000..47932a6 Binary files /dev/null and b/flute/filemanage.o differ diff --git a/flute/flute.o b/flute/flute.o new file mode 100644 index 0000000..9723d6b Binary files /dev/null and b/flute/flute.o differ diff --git a/flute/flute.vcproj b/flute/flute.vcproj new file mode 100644 index 0000000..f8bf347 --- /dev/null +++ b/flute/flute.vcproj @@ -0,0 +1,151 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/flute/flute_cb.o b/flute/flute_cb.o new file mode 100644 index 0000000..e6fa428 Binary files /dev/null and b/flute/flute_cb.o differ diff --git a/flute/flute_fdt.o b/flute/flute_fdt.o new file mode 100644 index 0000000..2a58880 Binary files /dev/null and b/flute/flute_fdt.o differ diff --git a/flute/flute_lock.o b/flute/flute_lock.o new file mode 100644 index 0000000..86fd997 Binary files /dev/null and b/flute/flute_lock.o differ diff --git a/flute/flute_md5.o b/flute/flute_md5.o new file mode 100644 index 0000000..293c802 Binary files /dev/null and b/flute/flute_md5.o differ diff --git a/flute/flute_sdp.cpp b/flute/flute_sdp.cpp new file mode 100644 index 0000000..05aa849 --- /dev/null +++ b/flute/flute_sdp.cpp @@ -0,0 +1,246 @@ +/* $Id: flute_sdp.cpp,v 1.4 2005/03/23 14:05:01 roca Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * flute_sdp.cpp + * + * Flute sdp parser. + */ + +#include "flute.h" + + + +flute_sdp::flute_sdp () +{ + this->media_part = false; +} + + + +flute_sdp::~flute_sdp () +{ + this->media_part = false; +} + + + +int flute_sdp_field_handler( + SDP_Parser * parser, + char type, + const char * value, + void * user_data) + { + char * temp; /* temp string for string search operations */ + + switch(type) { + case 'v': + case 'o': + case 'i': + case 't': + break; + case 'a': + if (!strncmp(value, "flute-tsi:", 10) && isdigit((int)*(value+10))) { + ((flute_cb *) user_data)->demux_label = atoi(value+10); + } + else if (!strncmp(value, "flute-ch:", 9) && isdigit((int)*(value+9))){ + ((flute_cb *) user_data)->nb_layers = atoi(value+9); + } + else if (!strncmp(value, "source-filter:", 14) && isdigit((int)*(value+14))){ + if (((flute_cb *) user_data)->sdp->media_part == true) + /* source filters not allowed in media part */ + return SDP_FAILURE; + + if ((temp = strstr(value,"excl")) != NULL) + /* exclusive source filters not allowed */ + return SDP_FAILURE; + + if ((temp = strstr(value,"IN")) == NULL) + /* only IN source filters allowed */ + return SDP_FAILURE; + + + if ((temp = strstr(value,"IP4")) != NULL) + { +#ifdef WIN32 + ((flute_cb *) user_data)->ip_version = 4; +#endif + } + else if ((temp = strstr(value,"IP6")) != NULL) + { +#ifdef WIN32 + ((flute_cb *) user_data)->ip_version = 6; +#endif + + } + + /* get the IP address string */ + temp = strstr(value,"* "); + strncpy(((flute_cb *) user_data)->source_addr_str, temp+2, sizeof(((flute_cb *) user_data)->source_addr_str)); + ((flute_cb *) user_data)->source_addr_str[255] = '\0'; + if (extract_addr(((flute_cb *) user_data)->source_addr_str, &((flute_cb *) user_data)->src_addr, 0) < 0) { + EXIT(("Flute: ERROR, extract_addr failed for src_addr argument -s%s\n", optarg)) + } + + + if (!isdigit((int)*(temp+1))) + return SDP_FAILURE; + ((flute_cb *) user_data)->port = atoi(temp+1); + + } +#if 0 + else if (!strncmp(value, "FEC-declaration:", 16) && isdigit((int)*(value+16))){ + + } +#endif + break; + case 'm': + /* we are starting parsing the media part */ + if (((flute_cb *) user_data)->sdp->media_part == false) ((flute_cb *) user_data)->sdp->media_part = true; + + /* check if it is a FLUTE media type */ + temp = strstr(value,"FLUTE/UDP"); + if (temp == NULL) + return SDP_FAILURE; + + /* jump to the port number */ + /* (Normally the line looks like: * + * m=application 12345 FLUTE/UDP 0 */ + temp = strstr(value," "); + if (!isdigit((int)*(temp+1))) + return SDP_FAILURE; + ((flute_cb *) user_data)->port = atoi(temp+1); + break; + case 'c': + if ((temp = strstr(value,"IP4")) != NULL) + { +#ifdef WIN32 + ((flute_cb *) user_data)->ip_version = 4; +#endif + } + else if ((temp = strstr(value,"IP6")) != NULL) + { +#ifdef WIN32 + ((flute_cb *) user_data)->ip_version = 6; +#endif + + } + else + return SDP_FAILURE; + + /* get the IP address string */ + { + char *t,*c; + strncpy(((flute_cb *) user_data)->remote_addr_str, temp+4, sizeof(((flute_cb *) user_data)->remote_addr_str)); + /* ttl */ + if ((t = strchr(((flute_cb *) user_data)->remote_addr_str, '/')) != NULL) { + *t = '\0'; + /* number of channels */ + if ((c = strchr(t, '/')) != NULL){ + *c = '\0'; + } + /* in host order */ + ((flute_cb *) user_data)->ttl = (unsigned short)atoi(t+1); + } + ((flute_cb *) user_data)->remote_addr_str[255] = '\0'; + } + ((flute_cb *) user_data)->remote_address_set = true; + + default: + break; + } + return SDP_SUCCESS; + } + + + +void flute_sdp::flute_parse_sdp(char * sdp_filename) +{ + SDP_Parser *sdp_parser; + + sdp_parser = SDP_NewParser(); + + SDP_SetFieldHandler(sdp_parser, (SDP_FieldHandler) &flute_sdp_field_handler); + SDP_SetUserData(sdp_parser, (void *) flutecb); + + if (SDP_EventStreamParseFile(sdp_parser, sdp_filename)!=true) + { + EXIT(("Flute: ERROR, SDP file seems not OK (or some features are not supported by our implementation)\n")) + } + + SDP_DestroyParser(sdp_parser); +} + + + +void flute_sdp::flute_generate_sdp(char * sdp_filename) +{ + char temp[256]; + SDP_Generator *generator = SDP_NewGenerator(); + + SDP_GenProtocolVersionField(generator, 0); + + sprintf(temp,"%i",flutecb->demux_label); + SDP_GenAttributeField(generator,"flute-tsi", temp); + memset(temp,0, sizeof(temp)); + + if(flutecb->nb_layers > 0) + { + sprintf(temp,"%i\n",flutecb->nb_layers); + SDP_GenAttributeField(generator,"flute-ch", temp); + memset(temp,0, sizeof(temp)); + } + + sprintf(temp,"%i",flutecb->port); + SDP_GenMediaDescriptionField(generator,"data",temp,"FLUTE/UDP","0"); + memset(temp,0, sizeof(temp)); + + if (flutecb->addr != NULL) + { + if (flutecb->addr->sa_family == AF_INET) + { + SDP_GenConnectionField(generator,"IN", "IP4", inet_ntoa(((sockaddr_in*) flutecb->addr)->sin_addr), flutecb->ttl,1); + } + else if (flutecb->addr->sa_family == AF_INET6) + { +#ifdef WIN32 + DWORD len = INET6_ADDRSTRLEN; + if (WSAAddressToString( (LPSOCKADDR) flutecb->addr, sizeof(struct sockaddr_in6), NULL, temp, &len)!=0) + { + EXIT(("Flute::flute_generate_sdp: ERROR, WSAStringToAddress failed: %i\n", WSAGetLastError())) + } + +#else /* UNIX */ + inet_ntop(AF_INET6, &(((struct sockaddr_in6*)flutecb->addr)->sin6_addr),temp, sizeof(temp)); +#endif + SDP_GenConnectionField(generator,"IN", "IP6", temp, flutecb->ttl,1); + } + } + else + { + SDP_GenConnectionField(generator,"IN", "IP4", "127.0.0.1", flutecb->ttl,1); + } + + SDP_SaveGeneratedOutput(generator,sdp_filename); +} + diff --git a/flute/flute_sdp.o b/flute/flute_sdp.o new file mode 100644 index 0000000..aedddbf Binary files /dev/null and b/flute/flute_sdp.o differ diff --git a/flute/frecv.cpp b/flute/frecv.cpp new file mode 100644 index 0000000..bcb0535 --- /dev/null +++ b/flute/frecv.cpp @@ -0,0 +1,47 @@ +/* $Id: frecv.cpp,v 1.12 2005/05/12 16:03:30 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * frecv.c + * + * flute receiver side functions + */ +#include "../src/flute_lib/FluteAPI.h" +#include "frecv.h" +#include "macros.h" + +extern class FluteReceiver *myflutereceiver; +extern bool interactive; + +void FluteRecv(void) +{ + UINT64 Bytes_received = 0; + + myflutereceiver->setSelectAll (!interactive); + + PRINT(("Waiting for data...\n")) + Bytes_received = myflutereceiver->recv(true); + PRINT(("\nFluteRecv completed, %llu bytes received\n", Bytes_received)) +} + diff --git a/flute/frecv.h b/flute/frecv.h new file mode 100644 index 0000000..dd5eba0 --- /dev/null +++ b/flute/frecv.h @@ -0,0 +1,33 @@ +/* $Id: frecv.h,v 1.4 2004/07/16 14:55:29 roca Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * frecv.h + * + * flute receiver side functions headers + */ + +void FluteRecv (void); +int RecvOneFile (void); +int RecvFiles (void); diff --git a/flute/fsend.cpp b/flute/fsend.cpp new file mode 100644 index 0000000..202525d --- /dev/null +++ b/flute/fsend.cpp @@ -0,0 +1,252 @@ +/* $Id: fsend.cpp,v 1.13 2005/05/12 16:03:30 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * fsend.c + * + * flute sender side functions + */ +#include "../src/flute_lib/FluteAPI.h" +#include "fsend.h" +#include "file_tools.h" +#include "macros.h" + +extern char **fileparam; +extern class FluteSender *myflutesender; +extern int nb_tx; + + +void FluteSend (void) +{ + UINT64 Bytes_sent = 0; + + int i = 0; + while(fileparam[i] != NULL && i < MAXNUMBER_OF_FILES) + { +#ifdef WIN32 + WIN32_FIND_DATA entry; + FindFirstFile(fileparam[i], &entry); + if (entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) +#else + struct stat stats; + stat(fileparam[i], &stats); + if (S_ISDIR(stats.st_mode)) +#endif + { + RecursiveSend(fileparam[i]); + } + else { + SendThisFile(fileparam[i]); + } + i++; + } + + Bytes_sent = myflutesender->carousel->startTxCycles(nb_tx,true); + + /* free list of files */ + i = 0; + while(fileparam[i] != NULL && i < MAXNUMBER_OF_FILES) { + free(fileparam[i]); + i++; + } + free(fileparam); + + PRINT(("\nFluteSend complete. %llu bytes sent\n", Bytes_sent)) +} + + +#ifdef WIN32 + +void RecursiveSend (char* Path) +{ + + HANDLE dirp = NULL; + WIN32_FIND_DATA entry; + + char FullName[MAX_PATH + MAX_FILENAME]; + char FindString[MAX_PATH]; + strcpy(FindString, Path); + strcat(FindString, "\\*"); + + dirp = FindFirstFile(FindString, &entry); + + if (dirp == INVALID_HANDLE_VALUE) + { + EXIT(("Flute: ERROR, in recursive mode, the given parameter MUST BE a valid directory name\nAborting...\n")) + } + + if (!IsDirDots (entry.cFileName)) + { + strcpy(FullName, Path); + if(FullName[strlen(FullName)-1] == '\\') + FullName[strlen(FullName)-1] = '/'; + + if(FullName[strlen(FullName)-1] != '/') + strcat(FullName,"/"); + + strcat(FullName, entry.cFileName); + + if( entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + ASSERT((strcmp(Path,FullName))); + PRINT(("Entering Directory %s\n", FullName)); + RecursiveSend (FullName); + } + else + { + PRINT(("\nSending File %s\n", FullName)) + SendThisFile (FullName); + } + } + + while ( FindNextFile(dirp, &entry) ) + { + if (IsDirDots (entry.cFileName)) + continue; + + strcpy(FullName, Path); + if(FullName[strlen(FullName)-1] == '\\') + FullName[strlen(FullName)-1] = '/'; + + if(FullName[strlen(FullName)-1] != '/') + strcat(FullName,"/"); + + strcat(FullName, entry.cFileName); + + if( entry.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + ASSERT((strcmp(Path,FullName))) + PRINT(("Entering Directory %s\n", FullName)) + RecursiveSend (FullName); + } + else + { + PRINT(("\nSending File %s\n", FullName)) + SendThisFile (FullName); + } + } + FindClose(dirp); +} + + +#else + +void RecursiveSend (char* Path) +{ + struct dirent *entry; + struct stat stats; + char FullName[MAX_PATH + MAX_FILENAME]; + DIR *dirp; + + if ((dirp = opendir (Path)) == NULL) + { + perror(Path); + EXIT(("RecursiveSend: ERROR, opendir failed\n")) + } + + /* + For SOLARIS users: + Why doesn't readdir work? It chops the first two characters of + all filenames. + + You're probably linking with libucb and didn't read question + 6.18. (Readdir in libucb.so wants you to include sys/dir.h, + but many SunOS 4.1.x programs included , consequently, + you're mixing native struct dirent with libucb + readdir(). The symptom of this mixup is that the first two + characters of each filename are missing. Make sure you use a + native compiler (default /opt/SUNWspro/bin/cc, which may not be in + your PATH), and not /usr/ucb/cc. + */ + + while ((entry = readdir(dirp)) != NULL) { + if (IsDirDots (entry->d_name)) + continue; + + strcpy(FullName, Path); + if (FullName[strlen(FullName)-1] != '/') + strcat(FullName, "/"); + + strcat(FullName, entry->d_name); + + if (stat(FullName, &stats) == -1) { + perror("RecursiveSend: ERROR, stat failed"); + PRINT(("RecursiveSend: FullName=%s\nentry->d_name=%s\nPath=%s\n", FullName, entry->d_name, Path)) + EXIT(("RecursiveSend: ERROR, stat() failed\n")) + } + + if (S_ISDIR(stats.st_mode)) { + ASSERT((strcmp(Path,FullName))) + PRINT(("Entering Directory %s\n", FullName)) + RecursiveSend (FullName); + } else { + PRINT(("Sending File %s\n", FullName)) + SendThisFile (FullName); + } + } + closedir (dirp); +} + +#endif + + + +TOI_t SendThisFile (char *file_path) +{ + + struct stat file_stats; + int file_to_send = 0; + TOI_t toi = 0; + + if (FileExist(file_path)) { + if (stat(file_path, &file_stats) == -1) { + EXIT(("Flute: SendThisFile: Error: stat()\n")) + //PRINT(("Flute: SendThisFile: Error: stat()\n")) + //goto end; + } +#ifdef WIN32 + file_to_send = open(file_path, O_RDONLY | O_BINARY); +#else + file_to_send = open(file_path, O_RDONLY); +#endif + if (file_to_send < 0) { + EXIT(("Flute: open failed for file %s\n", file_path)) + } + } else { + PRINT(("Flute: SendThisFile: Error: %s, no such file!\n", file_path)) + close(file_to_send); + return 0; + } + if (!(file_stats.st_mode & S_IFREG)) + EXIT(("Flute: SendThisFile: Error: %s is not a regular file\n", file_path)) + + + close(file_to_send); + + myflutesender->carousel->addFile(file_path); + + return toi; +} + + diff --git a/flute/fsend.h b/flute/fsend.h new file mode 100644 index 0000000..2c14993 --- /dev/null +++ b/flute/fsend.h @@ -0,0 +1,39 @@ +/* $Id: fsend.h,v 1.5 2005/05/12 16:03:30 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * fsend.h + * + * flute sender side functions headers + */ +#ifndef WIN32 +#include +#endif + +extern void FluteSend (void); +extern TOI_t SendThisFile (char*); +extern void RecursiveSend (char*); + + + diff --git a/flute/getopt.cpp b/flute/getopt.cpp new file mode 100644 index 0000000..9c812c0 --- /dev/null +++ b/flute/getopt.cpp @@ -0,0 +1,151 @@ +/* $Id: getopt.cpp,v 1.2 2005/05/12 16:03:31 moi Exp $ */ +/////////////////////////////////////////////////////////////////////////////// +// +// FILE: getopt.c +// +// GetOption function +// +// FUNCTIONS: +// +// GetOption() - Get next command line option and parameter +// +// COMMENTS: +// +/////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include "getopt.h" + +/////////////////////////////////////////////////////////////////////////////// +// +// FUNCTION: GetOption() +// +// Get next command line option and parameter +// +// PARAMETERS: +// +// argc - count of command line arguments +// argv - array of command line argument strings +// pszValidOpts - string of valid, case-sensitive option characters, +// a colon ':' following a given character means that +// option can take a parameter +// ppszParam - pointer to a pointer to a string for output +// +// RETURNS: +// +// If valid option is found, the character value of that option +// is returned, and *ppszParam points to the parameter if given, +// or is NULL if no param +// If standalone parameter (with no option) is found, 1 is returned, +// and *ppszParam points to the standalone parameter +// If option is found, but it is not in the list of valid options, +// -1 is returned, and *ppszParam points to the invalid argument +// The variable optind is the index of the element of the argv[] +// vector to be processed. +// When end of argument list is reached, 0 is returned, and +// *ppszParam is NULL +// +// COMMENTS: +// +/////////////////////////////////////////////////////////////////////////////// + +int GetOption ( + int argc, + char** argv, + char* pszValidOpts, + char** ppszParam, + int * optind) +{ + static int iArg = 1; + char chOpt; + char* psz = NULL; + char* pszParam = NULL; + + if (iArg < argc) + { + psz = &(argv[iArg][0]); + if (*psz == '-' || *psz == '/') + { + // we have an option specifier + chOpt = argv[iArg][1]; + if (isalnum(chOpt) || ispunct(chOpt)) + { + // we have an option character + psz = strchr(pszValidOpts, chOpt); + if (psz != NULL) + { + // option is valid, we want to return chOpt + if (psz[1] == ':') + { + // option can have a parameter + psz = &(argv[iArg][2]); + if (*psz == '\0') + { + // must look at next argv for param + if (iArg+1 < argc) + { + psz = &(argv[iArg+1][0]); + if (*psz == '-' || *psz == '/') + { + // next argv is a new option, so param + // not given for current option + } + else + { + // next argv is the param + iArg++; + pszParam = psz; + } + } + else + { + // reached end of args looking for param + } + + } + else + { + // param is attached to option + pszParam = psz; + } + } + else + { + // option is alone, has no parameter + } + } + else + { + // option specified is not in list of valid options + chOpt = -1; + pszParam = &(argv[iArg][0]); + } + } + else + { + // though option specifier was given, option character + // is not alpha or was was not specified + chOpt = -1; + pszParam = &(argv[iArg][0]); + } + } + else + { + // standalone arg given with no option specifier + chOpt = 1; + pszParam = &(argv[iArg][0]); + } + } + else + { + // end of argument list + chOpt = 0; + } + + *optind = iArg; + iArg++; + *ppszParam = pszParam; + return (chOpt); +} diff --git a/flute/getopt.h b/flute/getopt.h new file mode 100644 index 0000000..ca69bc4 --- /dev/null +++ b/flute/getopt.h @@ -0,0 +1,13 @@ +/* $Id: getopt.h,v 1.3 2005/05/12 16:03:31 moi Exp $ */ +/////////////////////////////////////////////////////////////////////////////// +// +// FILE: getopt.h +// +// Header for the GetOption function +// +// COMMENTS: +// +/////////////////////////////////////////////////////////////////////////////// + +// function prototypes +int GetOption (int argc, char** argv, char* pszValidOpts, char** ppszParam, int * optind); diff --git a/flute/macros.h b/flute/macros.h new file mode 100644 index 0000000..79968b4 --- /dev/null +++ b/flute/macros.h @@ -0,0 +1,68 @@ +/* $Id: macros.h,v 1.5 2005/05/12 16:03:31 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#ifndef MACROS_H +#define MACROS_H + +#include +#include + +/****** general macros ******/ + +#ifndef min +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#endif +#ifndef max +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#endif + +/* + * print to stdout + */ +#define PRINT(a) { printf a; fflush(stdout); } + +/* + * print and exit + */ +#define EXIT(a) { printf a; fflush(stdout); exit(-1); } + +/* + * test, print and exit if error (i.e. if != 0) + */ +#define EXIT_ON_ERROR(err, a) { if (err) { EXIT(a) } } + + +#define ASSERT(c) { \ + if (!(c)) { \ + fprintf(stderr, "ASSERT [%s:%d] failed\n", \ + __FILE__, __LINE__); \ + fflush(stderr); \ + exit (-1); \ + } \ + } + +#define BUFFER_TO_INT32(x) ((*(x)<<24) + (*(x+1)<<16) + (*(x+2)<<8) + (*(x+3))) + + +#endif diff --git a/flute/main.cpp b/flute/main.cpp new file mode 100644 index 0000000..c1b508f --- /dev/null +++ b/flute/main.cpp @@ -0,0 +1,556 @@ +/* $Id: main.cpp,v 1.5 2005/05/23 11:11:26 roca Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * flute.c + * + * Flute file transfert tool over the Flute Library. + */ +#include "../src/flute_lib/FluteAPI.h" +#include "fsend.h" +#include "frecv.h" +#include "display.h" +#include "macros.h" +#ifdef WIN32 +#include "getopt.h" +#endif + +static void Usage (int argc, char *argv[]); +static void ParseCommandLine (int argc, char *argv[]); +static void interrupted (void); + +/* the flute session class */ +class Flute *myflute = NULL; +class FluteSender *myflutesender = NULL; +class FluteReceiver *myflutereceiver = NULL; + +/* some global parameters */ +#ifdef WIN32 +bool pause = 0; /* Request user input (pause) before exiting or not */ +#endif +bool interactive = false; +char **fileparam = NULL; +int nb_tx = 1; + +int main (int argc, char *argv[]) +{ + + /* variables for display thread*/ + flute_thread_t thread_display; + + signal(SIGINT, (sighandler_t)interrupted); + + /* Parameters parsing... + * This call also creates the sender or receiver FLUTE session + */ + ParseCommandLine(argc, argv); + +#ifdef WIN32 + if (myflute->getVerbosity() == 0 && myflute->getStatsLevel() == 0) { + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) display, (void*)NULL, 0, (LPDWORD)&thread_display); + } +#else + if (myflute->getVerbosity() == 0 && myflute->getStatsLevel() == 0) { + pthread_create(&thread_display, NULL, display, (void *)NULL); + } +#endif + + + if (myflute->isSender()) + { + myflutesender = (class FluteSender *) myflute; + FluteSend(); + } + else if (myflute->isReceiver()) + { + myflutereceiver = (class FluteReceiver *) myflute; + FluteRecv(); + } + else if (myflute->isSender() == false && myflute->isReceiver() == false) + { + PRINT(("Error: -send or -recv mode required\n")) + Usage(argc, argv); + return -1; + } + +#ifndef WIN32 + if (myflute->getVerbosity() == 0 && myflute->getStatsLevel() == 0) pthread_cancel(thread_display); +#endif + +#ifdef WIN32 + if (pause) { + system("pause"); + } + WSACleanup(); +#endif + + /* now free and delete everything */ + if (myflute->isSender()) + { + delete myflutesender; + } + else if (myflute->isReceiver()) + { + delete myflutereceiver; + } + else delete myflute; + + return 0; +} + + +void Usage (int argc, char *argv[]) +{ + + PRINT(("\nFLUTE Multicast File Transfert Tool\n")) + + if (myflute == NULL || myflute->isReceiver() == true) { + myflute = new FluteSender(); + } + myflute->about(); + + PRINT(("\n\n")) + PRINT(("USAGE (sender) %s -send [options] {file|directory}\n", argv[0])) + PRINT((" (receiver) %s -recv [options] \n\n", argv[0])) + PRINT(("COMMON OPTIONS (NB: do not use extra space in arguments)\n")) + PRINT((" -help this help\n")) + PRINT((" -send or -recv choose Flute mode: sender or receiver.\n")) + PRINT((" -an[/p] set uni/multicast IPv4/IPv6 address or name to n and\n")) + PRINT((" port number to p (default 127.0.0.1/%d)\n", myflute->getPort())) +#ifdef WIN32 + PRINT((" -ipvn IP version, 4 or 6 (Win32 specific) (default: 4)\n")) +#endif + PRINT((" -ssm use SSM (source specific multicast) (default: no)\n")) + PRINT((" -ifan (InterFace Address) the network interface to use is the\n")) + PRINT((" one attached to the local IPv4/IPv6 addr or host name n\n")) + PRINT((" Only used on multi-homed hosts/routers.\n")) + PRINT((" -ifnstr (InterFace Name) the network interface to use is the\n")) + PRINT((" one attached to the interface name str (e.g. -ifneth0)\n")) + PRINT((" Only used on multi-homed hosts/routers.\n")) + PRINT((" -demuxn set the LCT Transport Session Id (TSI) to n (default 0)\n")) + PRINT((" - at a sender TSI is included in each packet sent\n")) + PRINT((" - at a receiver {src_addr; TSI} is used for packet filtering\n")) + PRINT((" -vn set (MCL) verbosity level to n (add statistics too)\n")) + PRINT((" -statn set (MCL) statistic level to n (0: none, 1: final, 2: all)\n")) + PRINT((" -tmpdir the temporary directory is dir (string)\n")) + PRINT((" (unix default: \"/tmp\")\n")) +#ifdef WIN32 + PRINT((" -P Request user input (pause) before exiting (for win console)\n")) +#endif + PRINT(("TRANSMISSION PROFILES\n")) + PRINT((" one can use either predefined profiles, or do everything by hand\n")) + PRINT((" or redefine some parameters of the predefined profiles\n")) + PRINT((" -plow | -pmed | -phigh predefined tx profiles for Low|Medium|High\n")) + PRINT((" Speed Internet. (default: medium)\n")) + PRINT((" specifies: number of layers, rate on base layer, datagram\n")) + PRINT((" size, and either FLID-SL (default) or RLC cong. control\n")) + PRINT((" -plan predefined tx profile for High Speed LAN\n")) + PRINT((" specifies: 1 layer, rate, datagram size, and no cong.\n")) + PRINT((" control\n")) + PRINT((" -psize[/rate] sets one (or two) parameters:\n")) + PRINT((" size is the datagram size (bytes) (used by sender/recv)\n")) + PRINT((" rate is the base layer tx rate (bits/s) (used by sender)\n")) +#if defined(ALC) + PRINT((" -ln set number of layers to n\n")) + PRINT((" -ccn set congestion control (CC) scheme to n:\n")) + PRINT((" 0 for no CC (automatically selects 1 transmission layer)\n")) + PRINT((" 1 for RLC (often needed for interoperability tests)\n")) + PRINT((" 2 for FLID_SL (default, less aggressive than RLC)\n")) + PRINT((" Must be specified on both sender and receivers sides!\n")) +#endif + PRINT(("SENDER SPECIFIC OPTIONS\n")) + PRINT((" -ttln set the ttl (time to live) to n (default 1)\n")) + PRINT((" -cont continuous delivery mode (same as -repeat)\n")) + PRINT((" also known as ``on-demand'' mode (default is ``push'')\n")) + PRINT((" -repeatn repeat n times on each layer then stop\n")) + PRINT((" ignored in ``on-demand mode''\n")) + PRINT((" -fecn set FEC expansion ratio to n, floating point value >= 1.0.\n")) + PRINT((" (default is %.2f). A ratio of 1.0 means no FEC as it is\n", ((FluteSender *)myflute)->getFECRatio())) + PRINT((" the n/k ratio, inverse of the so-called \"code rate\".\n")) + PRINT((" -createsdpstr create an SDP file for that session\n")) + PRINT((" the result will be written to the file str (string)\n")) + + PRINT(("RECEIVER SPECIFIC OPTIONS\n")) + PRINT((" -srcn set the IPv4/IPv6 source address or name to n (default 0)\n")) + PRINT((" Mandatory in SSM mode.\n")) + PRINT((" {src_addr; TSI} is used for incoming packet filtering.\n")) + PRINT((" -parsesdpstr parse an SDP file, of pathname str (string), for that \n")) + PRINT((" session and set the parameters accordingly\n")) +#ifndef WIN32 + PRINT((" -int interactive mode where the user select files to be received\n")) + PRINT((" (default is to receive all files and overwrite existing\n")) + PRINT((" files when needed).\n")) + PRINT((" Move with up/down arrows, select with ENTER.\n")) +#else + PRINT((" -int|-never|-force set the overwriting mode:\n")) + PRINT((" interactive: user is prompted if file already exists\n")) + PRINT((" never: never overwrite an existing file\n")) + PRINT((" force: always write file, even if it already exists\n")) +#endif +#ifndef WIN32 + PRINT(("Type \"q\" to abort FLUTE\n")) +#else + PRINT(("Type \"CTRL-C\" to abort FLUTE\n")) + system("pause"); +#endif + + /* now free and delete everything */ + if (myflute->isSender()) + { + delete (class FluteSender *)myflute; + } + else if (myflute->isReceiver()) + { + delete (class FluteReceiver *)myflute; + } + else delete myflute; + + exit(0); +} + + +/* + * + */ +void ParseCommandLine (int argc, char *argv[]) +{ + int c; + char *OptList = "a:v:h:l:s:r:p:f:n:i:c:RPt:d:"; + bool create_sdp = false; + char sdp_file[MAX_PATH + MAX_FILENAME]; + +#ifdef SOLARIS + extern char *optarg; +#elif defined(WIN32) + char *optarg = NULL; + int optind = 0; +#endif + + if(argc < 2) { + Usage(argc, argv); + } + + for (int i = 0; i < argc; i++) { + if (!strcmp(argv[i], "-recv")) + myflute = new FluteReceiver(); + else if (!strcmp(argv[i], "-send")) + myflute = new FluteSender(); + } + /* We must select sender or receiver */ + if (myflute == NULL) { + EXIT(("Flute: ERROR, you must specify either -send or -recv\n")) + } + +#ifdef WIN32 + while ((c = GetOption(argc, argv, OptList, &optarg, &optind)) != 0 && c != 1) +#else + while ((c = getopt(argc, argv, OptList)) != EOF) +#endif + { + switch (c) { + case 'a': + /* process addr/port argument */ + char *p; + char session_addr_str[256]; + int port; + + if (*optarg == '\0') { + EXIT(("Flute: ERROR, bad argument -a%s: do not use extra space\n", + optarg)) + } + strncpy(session_addr_str, optarg, sizeof(session_addr_str)); + session_addr_str[255] = '\0'; + if ((p = strchr(session_addr_str, '/')) != NULL) { + *p = '\0'; + /* in host order */ + port = (unsigned short)atoi(p+1); + myflute->setPort(port); + } + myflute->setSessionAddr(session_addr_str); + break; + case 'd': + if (!strncmp(optarg, "emux", 4) && isdigit((int)*(optarg+4))) { + int tsi = atoi(optarg+4); + myflute->setTSI(tsi); + } + else + EXIT(("Flute: ERROR, bad argument -d%s (NB: dont use space between -demux and value)\n", optarg)) + break; + case 'v': /* verbosity level */ + if (isdigit((int)*optarg)) { + int verbosity = atoi(optarg); + myflute->setVerbosity(verbosity); + } else + EXIT(("Flute: ERROR, bad argument -v%s\n", optarg)) + break; + case 'h': + Usage(argc, argv); + break; + case 'l': /* number of layers */ + if (isdigit((int)*optarg)) { + int nb_layers = atoi(optarg); + myflute->setNbLayers(nb_layers); + } else + EXIT(("Flute: ERROR, bad argument -l%s\n", optarg)) + break; + case 't': /* ttl value */ + if (!strncmp(optarg, "tl", 2) && + isdigit((int)*(optarg+2))) { + int ttl = atoi(optarg+2); + ((FluteSender *) myflute)->setTTL(ttl); + } else if(!strncmp(optarg, "mp", 2)) { + char tmp_dir[MAX_PATH + MAX_FILENAME]; + strncpy(tmp_dir, optarg+2, sizeof(tmp_dir)); + tmp_dir[MAX_PATH + MAX_FILENAME-1] = 0; + /* add final / and \0 if not already present */ + if (tmp_dir[strlen(tmp_dir)-1] != '/' && + strlen(tmp_dir) <= MAX_PATH + MAX_FILENAME -2) + strcat(tmp_dir, "/"); + ((FluteReceiver *) myflute)->setTmpDir(tmp_dir); + } + else + EXIT(("Flute: ERROR, bad argument -t%s\n", optarg)) + break; + case 's': + if (!strncmp(optarg, "end", 3)) { + /* already processed */ + } else if (!strncmp(optarg, "sm", 2)) { + bool set = true; + ((FluteReceiver *) myflute)->setSSM(set); + } else if (!strncmp(optarg, "rc", 2)) { + /* process addr argument */ + char source_addr_str[256]; + if (*(optarg + 2) == '\0') { + EXIT(("Flute: ERROR, bad argument -s%s: do not use extra space\n", optarg)) + } + strncpy(source_addr_str, optarg + 2, sizeof(source_addr_str)); + source_addr_str[255] = '\0'; + ((FluteReceiver *) myflute)->setSrcAddr(source_addr_str); + + } else if(!strncmp(optarg, "tat", 3)) { + if (isdigit((int)*(optarg+3))) + { + int stats = atoi(optarg+3); + myflute->setStatsLevel(stats); + } + else + EXIT(("Flute: ERROR, bad argument -s%s\n (NB: dont use space between -stat and value)", optarg)) + } else + EXIT(("Flute: ERROR, bad argument -s%s\n", optarg)) + break; + case 'r': + if (!strncmp(optarg, "ecv", 3)) { + /* already processed */ + } else if(!strncmp(optarg, "epeat", 5) && + isdigit((int)*(optarg+5))) { + /* nb of tx is original_tx + repeat_nb*/ + nb_tx = atoi(optarg+5) + 1; + } else + EXIT(("Flute: ERROR, bad argument -r%s (NB: dont use space between -repeat and value)\n", optarg)) + break; + case 'p': + if (!strcmp(optarg, "low")) { + myflute->setTxProfile(MCL_TX_PROFILE_LOW_RATE_INTERNET); + } else if(!strcmp(optarg, "med")) { + myflute->setTxProfile(MCL_TX_PROFILE_MID_RATE_INTERNET); + } else if(!strcmp(optarg, "high")) { + myflute->setTxProfile(MCL_TX_PROFILE_HIGH_SPEED_INTERNET); + } else if(!strcmp(optarg, "lan")) { + myflute->setTxProfile(MCL_TX_PROFILE_HIGH_SPEED_LAN); + } else if(!strncmp(optarg, "arsesdp", 7)) { + strncpy(sdp_file, optarg+7, sizeof(sdp_file)); + sdp_file[MAX_PATH + MAX_FILENAME-1] = 0; + myflute->parseSdp(sdp_file); + } else if (*optarg) { + /* process size/rate argument */ + char str[128]; /* size/rate string */ + char *p; + int rate = 0; + + strncpy(str, optarg, sizeof(str)); + str[127] = '\0'; + if ((p = strchr(str, '/')) != NULL) { + *p = '\0'; /* cut str into two strings*/ + rate = (int)atoi(p+1); + if (rate <= 0) { + EXIT(("Flute: ERROR, invalid rate for argument -p%s (must be > 0)\n", optarg)) + } + } + int txprof_dt_size = (int)atoi(str); + if (txprof_dt_size <= 0) { + EXIT(("Flute: ERROR, invalid size for argument -p%s\n", optarg)) + } + myflute->setDatagramSize(txprof_dt_size); + myflute->setTxRate(rate); + } else { + EXIT(("Flute: ERROR, bad argument -p%s\n", optarg)) + } + break; + + case 'P': +#ifdef WIN32 + pause = 1; +#endif + break; + + case 'f': + if (!strncmp(optarg, "ec", 2)) { + if (isdigit((int)*(optarg+2))) { + float fec_ratio = (float)atof(optarg+2); + ((FluteSender*) myflute)->setFECRatio(fec_ratio); + } else + EXIT(("Flute: ERROR, bad argument -f%s (NB: dont use space between -fec and value)\n", optarg)) +#ifdef WIN32 + } else if (!strcmp(optarg, "orce")) { + ((FluteReceiver*) myflute)->setOverwriteFile(ALWAYS); +#endif + } else + EXIT(("Flute: ERROR, bad argument -f%s\n", optarg)) + break; +#ifdef WIN32 + case 'n': + if (!strcmp(optarg, "ever")) { + ((FluteReceiver*) myflute)->setOverwriteFile(NEVER); + } else + EXIT(("Flute: ERROR, bad argument -n%s\n", optarg)) + break; +#endif + case 'c': + if (!strcmp(optarg, "ont")) { + nb_tx = CONTINUOUS; + } else if(!strncmp(optarg, "reatesdp", 8)) { + strncpy(sdp_file, optarg+8, sizeof(sdp_file)); + sdp_file[MAX_PATH + MAX_FILENAME-1] = 0; + create_sdp = true; + } else if (!strncmp(optarg, "c", 1)) { + int temp = (int)atoi(optarg+1); + switch(temp){ + case 0: + myflute->setCCScheme(NO_CC); + break; + case 1: + myflute->setCCScheme(RLC_CC); + break; + case 2: + myflute->setCCScheme(FLID_SL_CC); + break; + } + } else + EXIT(("Flute: ERROR, bad argument -c%s\n", optarg)) + break; + case 'i': +#ifndef WIN32 + if (!strcmp(optarg, "nt")) { + interactive=true; + ((FluteReceiver *)myflute)->setOverwriteFile(PROMPT); + } else if (!strncmp(optarg, "fn", 2)) { + /* this is an interface name */ + char name_str[256]; /* if name string */ + + if (*(optarg + 2) == '\0') { + EXIT(("Flute: ERROR, bad argument -i%s: do not use extra space\n", optarg)) + } + strncpy(name_str, optarg + 2, sizeof(name_str)); + strncpy(name_str, optarg + 2, 256); + name_str[255] = '\0'; + myflute->setInterfaceName(name_str); + } else if (!strncmp(optarg, "fa", 2)) { + /* process addr/hostname argument */ + if (*(optarg + 2) == '\0') { + EXIT(("Flute: ERROR, bad argument -i%s: do not use extra space\n", optarg)) + } + char interface_addr_str[256]; /* if name string */ + strncpy(interface_addr_str, optarg + 2, sizeof(interface_addr_str)); + interface_addr_str[255] = '\0'; + myflute->setInterface(interface_addr_str); + } +#else /*WIN32 */ + if (!strncmp(optarg, "pv", 2)) { + int ip_version = (int)atoi(optarg+2); + myflute->setIpVersion(ip_version); + } +#endif + else + EXIT(("Flute: ERROR, bad argument -i%s\n", optarg)) + break; + default: + /* + * NB: getopt returns '?' when finding an + * unknown argument; avoid the following + * error msg in that case + */ + if (c != '?') + PRINT(("bad argument %c\n", c)) + Usage(argc, argv); + break; + } + } + + ASSERT((argv[argc-1])) + + /* we went through all options */ + /* Now lets go through file names */ + if (myflute->isSender() == true) { + + if (argv[optind] == NULL) { + Usage(argc, argv); + } + + fileparam = (char**) calloc(1,MAXNUMBER_OF_FILES); + for (int i=optind; icreateSdp(sdp_file); + } + + + +} + + +/* + * we received a SIGINT... + */ +void +interrupted (void) +{ + static int abort_in_progress = 0; + + if (!abort_in_progress) { + abort_in_progress = 1; + PRINT(("Flute: aborted, call flute->abort()\n")); + myflute->abort(); + delete myflute; + PRINT(("Flute: aborted, exit\n")); + exit(2); + } /* else do nothing */ +} diff --git a/man/Makefile b/man/Makefile new file mode 100644 index 0000000..46515d1 --- /dev/null +++ b/man/Makefile @@ -0,0 +1,79 @@ +# $Id: Makefile,v 1.3 2004/12/21 16:18:26 roca Exp $ +# +# Makefile +# + +###### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Makefile.common + + +ifeq (${OS},linux) + # Linux version +endif + +ifeq (${OS},solaris) + # Solaris version +endif + + +###### Other Variables ###### + + +# List of source, object, and include files +# +# mclrecv2.man.1 +# mclsend2.man.1 +# mcl_open.man.3 +# mcl_ctl.man.3 +# mcl_wait_event.man.3 +# fcast.man.1 + +man_FILES = fcast.man.1 fcastn.man.1 flute.man.1 mclrecv2.man.1 mclsend2.man.1 mcl_open.man.3 mcl_ctl.man.3 mcl_wait_event.man.3 mcl_close.man.3 mcl_abort.man.3 mcl_send.man.3 mcl_recv.man.3 +html_FILES = fcast.man.1.html fcastn.man.1.html flute.man.1.html mclrecv2.man.1.html mclsend2.man.1.html mcl_open.man.3.html mcl_ctl.man.3.html mcl_wait_event.man.3.html mcl_close.man.3.html mcl_abort.man.3.html mcl_send.man.3.html mcl_recv.man.3.html +ps_FILES = ${html_FILES:.html=.ps.gz} + + +# General purpose local FLAGS. +# +FLAGS = + + +###### Dependancies ###### + +all: ${ps_FILES} ${html_FILES} + +ps: ${ps_FILES} + +html: ${html_FILES} + + +${ps_FILES}: ${man_FILES} + @for f in ${man_FILES} ; do \ + echo "create a compressed postscript version of manual $${f}... "; \ + if [ -f "$${f}.ps.gz" ] ; then \ + rm "$${f}.ps.gz"; \ + fi; \ + man -t "./$${f}" > "$${f}.ps"; \ + gzip "$${f}.ps"; \ + done + +${html_FILES}: ${man_FILES} + @for f in ${man_FILES} ; do \ + echo "create an HTML version of manual $${f}... "; \ + man2html "./$${f}" > "$${f}.html"; \ + done + #/usr/bin/groff -Thtml -mandoc "./$${f}" > "$${f}.html"; \ + +clean : + @for f in core ${ps_FILES} ${html_FILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + echo "$${f} removed"; \ + fi \ + done + +cleanall : clean + diff --git a/man/fcast.man.1 b/man/fcast.man.1 new file mode 100755 index 0000000..3b31e4c --- /dev/null +++ b/man/fcast.man.1 @@ -0,0 +1,508 @@ +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH FCAST "1" "" "MCLv3 Reference Manual" + +.SH NAME + +fcast \- send or receive files using the MultiCast Library (MCL) using +the ALC protocol + +.SH SYNOPSIS + +.B fcast +.nh +[\fB-h\fP[\fBelp\fP]] +[\fB-send\fP] +[\fB-recv\fP] +[\fB-a address\fP[\fB/port\fP]] +[\fB-ifa address\fP] +[\fB-ifn ifname\fP] +[\fB-demux demux_level\fP] +[\fB-v verbosity_level\fP] +[\fB-stat stat_level\fP] +[\fB-silent\fP] +[\fB-tmp tmp_dir_string\fP] +[\fB-objaggr\fP] +[\fB-o speed/space/cpu\fP] +[\fB-p low|med|high|lan\fP] +[\fB-p size\fP[\fB/rate\fP]] +[\fB-l nb_of_layers\fP] +[\fB-cc congestion_control_protocol\fP] +.\" [\fB-singlelayer (DEPRECATED)\fP] +[\fB-P\fP] +[\fB-t ttl\fP] +[\fB-R\fP] +[\fB-cont\fP] +[\fB-repeat n\fP] +[\fB-fec n\fP] +.\" [\fB-huge (DEPRECATED)\fP] +[\fB-src address\fP +[\fB-int\fP] +[\fB-never\fP] +[\fB-force\fP] +[\fBfile or directory\fP] +.hy + +At a sender: +.nf +.B fcast -send [options] file +.fi +.nf +.B fcast -send [options] -R directory +.fi + +At a receiver: +.nf +.B fcast -recv [options] +.fi + + +.SH DESCRIPTION + +.B fcast +is a multicast file distribution application built over the +MultiCast Library (MCLv3) which uses the ALC (Asynchronous +Layered Coding) reliable multicast protocol. +.B fcast +can run both as a sender or a receiver. +.B fcast +has many features like the ability to send recursively all the files +of a given directory and its subdirectories, and the possibility to be used +in +.B ``on-demand'' +or +.B ``push'' +mode. +.B fcast +communicates many meta-data information along with the files in +order to precisely re-construct the file at the receiver. +An application-level checksum (using the same algorithm as that of TCP) +is also used in order to detect possible transmission errors. + +.B fcast +and +.B flute +differ from the fact that the first one uses private, non standard, +solutions, while the second one strictly follows IETF standards. +.B fcast +is appropriate when looking for a simple yet efficient tool, while +.B flute +is appropriate when using IETF standardized solutions is mandatory, or +when a large set of files are sent within a session and receivers +may be interested only in a subset of them. +.B flute +filtering mechanism is in that case a real asset. +The two tools are otherwise sharing many similarities, as well +as most arguments. + + + +.SH OPTIONS + +The following arguments can be provided +.B both at a sending or receiving fcast. + +.TP +.B \-h[elp] +Gives the credits, the compilation parameters and all the possible +.B fcast +arguments. + +.TP +.B \-send or \-recv +Set the Fcast application mode to +.B sender +OR to +.B receiver. +You must ALWAYS specify one of these two modes. + +.TP +.B \-a address[/port] +Specifies the unicast or multicast IPv4 or IPv6 address of the base layer and its UDP +port number (if specified). +If no +.B -a +and/or +.B /port +argument is provided, then the default target address (usually that of +the loopback interface) and port number of MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port number). +.I (communicated to MCL) + +.TP +.B \-ifa address +The network interface to use is the one attached to the local address +specified (or hostname specified). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +The alternative is to use +.B \-ifn ifname. +.I (communicated to MCL) + +.TP +.B \-ifn ifname +The network interface to use is the one attached to the name +specified (e.g. +.B \-ifneth0 +). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +The alternative is to use +.B \-ifa address. +.I (communicated to MCL) + +.TP +.B \-demux N +Sets the LCT Transport Session Identifier (or TSI) to +.B N. +At a sender this TSI is included in each packet sent. +At a receiver are used to fully identify the ALC session +and to filter incoming packets. +If no +.B -demux +argument is provided, then any packet matching the source address (if +provided) will be accepted with the risk they belong to other sessions +(e.g if they use the same tuple). +This demux label is also usefull to make sure that the current session will +not get confused by packets from previous incarnation session. +The receivers and the sender must of course agree beforehand and use the +same value. +By default a value of 0 is used. +.I (communicated to MCL) + +.B \-v verbosity_level +Specifies the level of verbosity desired from the MCL library. +This option also automatically enables the \-stat 2 option to +add statistics. +Note that full verbosity requires that the MCL library be compiled in +DEBUG mode. +.I (communicated to MCL) + +.TP +.B \-stat stat_level +Specifies the level of statistics desired from the MCL library. +Level 0 (default) means nothing, level 1 means that only the final +statistics (at end of session) will be displayed, level 2 means that each +time an object is fully received, statistics are displayed. +.I (communicated to MCL) + +.TP +.B \-silent +Enables the silent mode (nothing is sent to stdout). + +.TP +.B \-tmp tmp_dir_string +Set the MCL temporary directory to be tmp_dir_string rather than its +default (usually "/tmp" with Unix). +The argument is a string, e.g. : +-tmp/home/roca/tmp +.I (communicated to MCL) + +.TP +.B \-objaggr +Enables the object aggregation mode. +This mode is highly efficient when sending a large number of small objects +(i.e. files) since FEC encoding now operates on the large object (that is the +result of the aggregation of all the small objects), rather than on +each small object. +Transmissions are an order of magnitude more efficient. +This solution is similar in spirit to the one described in +. +This mode requires that the recursive mode is set (to transmit several files). +.I (communicated to MCL) + +.TP +.B \-o space/speed/cpu +Specifies the optimization profile (in particular the order in which packets +are sent on each layer). +Possible values are: +.B space +to optimize the maximum memory space required at a receiver, +.B speed +to optimize the reception speed, and +.B cpu +to differ CPU intensive tasks at a receiver (recommanded on a +CPU bounded host). +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception optimization match, so use it on both ends. + + +.PP + +The following arguments define the transmission profiles. +One can use either a predefined profile, or do everything by hand, +or redefine some parameters of the predefined profiles. +These arguments must be specified at the sender and/or at the receiver, +as explained. + +.TP +.B \-p low|med|high|lan +Specifies the transmission profile. +Possible values are: +.B low +(low rate Internet), +.B med +(mid rate Internet), +.B high +(high speed Internet), and +.B lan +(high speed LAN). +If not specified, the default value of MCL is used instead. +The +.B -p size[/rate] +argument can be used instead (but not at the same time). +The +.B -plan +profile is dedicated to LAN environments, which means that no +congestion control is used (CCI field of the LCT header left to zero, which +also means that no loss statistics are possible), +and a single ALC layer is defined. Use with care... + +The exact parameters associated to each of these four profiles +can be changed either (1) with the +.B -l number_of_layers +or +.B -cc congestion_control_protocol +arguments, +or (2) by modifying the src/alc/mcl_tx_prof.cpp file. +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception profiles match, so specify the profile on both ends. + +.TP +.B \-p size[/rate] +Specifies the datagram size (in bytes) (at a sender or receiver), and +optionally the transmission rate (in bits/s) (only at a sender). +This argument cannot be used along with one of the +.B \-p low|med|high|lan +arguments. +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception profiles match, so specify it on both ends (only -p size at a receiver). + + +.TP +.B \-l number_of_layers +Specifies the maximum number of layers to use. +If not specified, the default value of MCL is used instead. +Note that a receiver is anyway constrained by the number of layers +offered by the source. +.I (communicated to MCL) + +.TP +.B \-cc congestion_control_protocol +Specifies the congestion control protocol to use. +.B -cc0 +specifies that NO CONGESTION CONTROL is used, and a single +layer is selected. +Use this mode only in appropriate environments, not over the Internet +where congestion control is mandatory. +This argument replaces the now deprecated "singlelayer" mode. +.B -cc1 +specifies RLC congestion control (often needed for interoperability tests). +.B -cc2 +specifies FLID-SL congestion control. This is the default, since this +protocol is less aggressive than RLC. +If nothing is specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.TP +.B \-singlelayer (DEPRECATED) +This argument is DEPRECATED and replaced by the -cc0 argument, +which must be used when no congestion control is required. +.TP + +.TP +.B \-P +If enabled, causes fcast to make a pause before exiting (WIN32 only). +Used to prevent the closing of console window when fcast is done, thus +giving some time to read outputs. + + +.PP + +The following arguments are +.B specific to a sender. + + +.TP +.B \-t ttl +Specifies the time to live (ttl) value of the IP header. +If not specified, the default value of MCL is used instead (usually 1). +Use \-t 1 if all the receivers are attached to the same LAN as the source. +.I (communicated to MCL) + +.TP +.B \-R +Enables the recursive mode. +Using this flag, fcast recursively sends the whole directory tree given as a +parameter. +At the receiver side, the same directory tree is created in the CURRENT +directory (fcast never goes upward). + +.TP +.B \-cont +Set the +.I continuous mode +for "on-demand" transmissions (i.e. receivers arrive +at their discretion, download the file and leave). +By default it is not set. +.I (communicated to MCL) + +.TP +.B \-repeat n +repeat n times the packet sequence on each layer. +Note that +.I \-repeat 0 +means that data is sent once. +By default, data is sent only once (no repeat) on a given layer in ``push'' +mode, and data is sent continuously in ``on-demand'' mode. +This parameter is usefull to increase the probability of good reception +at optimal speed by all receivers when working in ``push'' mode. +.I (communicated to MCL) + +.TP +.B \-fec n +Set the FEC ratio to n, a float point value greater or equal to 1.0. +This FEC ratio is the N/K ratio, of the +total number of symbols after FEC encoding (data + parity) to the +number of source symbols (data). +A default value of 2.0 is used, meaning that the number of parity +symbols is the same as the number of original source symbols. +Using +.I \-fec 1.0 +means that no parity packet will be produced. +.I (communicated to MCL) + + +.PP + +The following arguments are +.B specific to a receiver. + +.TP +.B \-src address +Specifies the unicast IPv4 or IPv6 address or name of the source. +At a receiver are used to fully identify the ALC session +and to filter incoming packets. +If no +.B -src +argument is provided, then any packet matching the TSI (if provided) +will be accepted with the risk they belong to other sessions +(e.g if they use the same tuple). +.I (communicated to MCL) + +.TP +.B \-int \-never or \-force +Sets the overwriting mode for an +.BFcast +receiver when a file to save already exists. +.B int +stands for interactive mode, meaning that the user will always be asked +before overwriting a file. +Using +.B never +, files are never overwritten. +Finally +.B force +means that any existing file will be automatically overwritten. +Default is +.B int +. Be carefull not to forget to answer to the question (especially in verbose +mode where the answer will quickly disappear!). + + +.PP + +In all cases, Fcast can be aborted by typing +.B CTRL\-C. + + +.SH EXAMPLE + +Here is a simple example where we send the file "foo.bar" +on group 225.1.2.3 (and above) : + +.nf +fcast -send -a225.1.2.3/2323 -v1 ./foo.bar +.fi + +A more complex example is the following, sending the whole directory "foobar/" +in object aggregation mode for higher transmission efficiency, over a LAN: + +.nf +fcast -send -a225.1.2.3/2323 -demux123 -stat1 -plan -objaggr -R foobar/ +.fi + +A receiver for the previous exemple: + +.nf +fcast -recv -R -a225.1.2.3/2323 -demux123 -stat1 -plan -objaggr -never +.fi + +Here is a session where we completely specify the transmission parameters +(1024 bytes of payload per packet, and 1Mbps transmission rate): + +.nf +fcast -send -a225.1.2.3/2323 -v1 -p1024/1000000 ./foo.bar +fcast -recv -a225.1.2.3/2323 -v1 -p1024 +.fi + + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2004 INRIA - All rights reserved +(main authors: Vincent ROCA - vincent.roca@inrialpes.fr + Julien LABOURE - julien.laboure@inrialpes.fr + Christoph NEUMANN - christoph.neumann@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR fcastn (1) +for the NORM version, +.BR mcl_ctl (3), +.BR MCL +documentation, and +INRIA Research Report 5225 for an introduction to LDGM-* large block +FEC codes. + + +.SH AUTHORS +.nf +Julien LABOURE (INRIA Rhone-Alpes, Planete project) +Vincent ROCA (INRIA Rhone-Alpes, Planete project) +.fi + +$Id: fcast.man.1,v 1.6 2004/12/17 11:53:12 roca Exp $ diff --git a/man/fcast.man.1.html b/man/fcast.man.1.html new file mode 100644 index 0000000..423190b --- /dev/null +++ b/man/fcast.man.1.html @@ -0,0 +1,651 @@ +Content-type: text/html + +Manpage of FCAST + +

FCAST

+Section: Misc. Reference Manual Pages (1)
Updated:
Index +Return to Main Contents
+ + +  +

NAME

+ + +fcast - send or receive files using the MultiCast Library (MCL) using +the ALC protocol + +  +

SYNOPSIS

+ + +fcast + + +[-h[elp]] +[-send] +[-recv] +[-a address[/port]] +[-ifa address] +[-ifn ifname] +[-demux demux_level] +[-v verbosity_level] +[-stat stat_level] +[-silent] +[-tmp tmp_dir_string] +[-objaggr] +[-o speed/space/cpu] +[-p low|med|high|lan] +[-p size[/rate]] +[-l nb_of_layers] +[-cc congestion_control_protocol] + +[-P] +[-t ttl] +[-R] +[-cont] +[-repeat n] +[-fec n] + +[-src address +[-int] +[-never] +[-force] +[file or directory] + + +At a sender: +
+fcast -send [options] file
+
+ +
+fcast -send [options] -R directory
+
+ + +At a receiver: +
+fcast -recv [options]
+
+ + + +  +

DESCRIPTION

+ + +fcast + +is a multicast file distribution application built over the +MultiCast Library (MCLv3) which uses the ALC (Asynchronous +Layered Coding) reliable multicast protocol. +fcast + +can run both as a sender or a receiver. +fcast + +has many features like the ability to send recursively all the files +of a given directory and its subdirectories, and the possibility to be used +in +``on-demand'' + +or +``push'' + +mode. +fcast + +communicates many meta-data information along with the files in +order to precisely re-construct the file at the receiver. +An application-level checksum (using the same algorithm as that of TCP) +is also used in order to detect possible transmission errors. + +fcast + +and +flute + +differ from the fact that the first one uses private, non standard, +solutions, while the second one strictly follows IETF standards. +fcast + +is appropriate when looking for a simple yet efficient tool, while +flute + +is appropriate when using IETF standardized solutions is mandatory, or +when a large set of files are sent within a session and receivers +may be interested only in a subset of them. +flute + +filtering mechanism is in that case a real asset. +The two tools are otherwise sharing many similarities, as well +as most arguments. + + + +  +

OPTIONS

+ + +The following arguments can be provided +both at a sending or receiving fcast. + + +
+
-h[elp] + +
+Gives the credits, the compilation parameters and all the possible +fcast + +arguments. + +
-send or -recv + +
+Set the Fcast application mode to +sender + +OR to +receiver. + +You must ALWAYS specify one of these two modes. + +
-a address[/port] + +
+Specifies the unicast or multicast IPv4 or IPv6 address of the base layer and its UDP +port number (if specified). +If no +-a + +and/or +/port + +argument is provided, then the default target address (usually that of +the loopback interface) and port number of MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port number). +(communicated to MCL) + + +
-ifa address + +
+The network interface to use is the one attached to the local address +specified (or hostname specified). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +The alternative is to use +-ifn ifname. + +(communicated to MCL) + + +
-ifn ifname + +
+The network interface to use is the one attached to the name +specified (e.g. +-ifneth0 + +). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +The alternative is to use +-ifa address. + +(communicated to MCL) + + +
-demux N + +
+Sets the LCT Transport Session Identifier (or TSI) to +N. + +At a sender this TSI is included in each packet sent. +At a receiver <src_addr; TSI> are used to fully identify the ALC session +and to filter incoming packets. +If no +-demux + +argument is provided, then any packet matching the source address (if +provided) will be accepted with the risk they belong to other sessions +(e.g if they use the same <multicast address, port> tuple). +This demux label is also usefull to make sure that the current session will +not get confused by packets from previous incarnation session. +The receivers and the sender must of course agree beforehand and use the +same value. +By default a value of 0 is used. +(communicated to MCL) + + +-v verbosity_level + +Specifies the level of verbosity desired from the MCL library. +This option also automatically enables the -stat 2 option to +add statistics. +Note that full verbosity requires that the MCL library be compiled in +DEBUG mode. +(communicated to MCL) + + +
-stat stat_level + +
+Specifies the level of statistics desired from the MCL library. +Level 0 (default) means nothing, level 1 means that only the final +statistics (at end of session) will be displayed, level 2 means that each +time an object is fully received, statistics are displayed. +(communicated to MCL) + + +
-silent + +
+Enables the silent mode (nothing is sent to stdout). + +
-tmp tmp_dir_string + +
+Set the MCL temporary directory to be tmp_dir_string rather than its +default (usually "/tmp" with Unix). +The argument is a string, e.g. : +-tmp/home/roca/tmp +(communicated to MCL) + + +
-objaggr + +
+Enables the object aggregation mode. +This mode is highly efficient when sending a large number of small objects +(i.e. files) since FEC encoding now operates on the large object (that is the +result of the aggregation of all the small objects), rather than on +each small object. +Transmissions are an order of magnitude more efficient. +This solution is similar in spirit to the one described in +<draft-neumann-rmt-flute-file-aggregation-00.txt>. +This mode requires that the recursive mode is set (to transmit several files). +(communicated to MCL) + + +
-o space/speed/cpu + +
+Specifies the optimization profile (in particular the order in which packets +are sent on each layer). +Possible values are: +space + +to optimize the maximum memory space required at a receiver, +speed + +to optimize the reception speed, and +cpu + +to differ CPU intensive tasks at a receiver (recommanded on a +CPU bounded host). +If not specified, the default value of MCL is used instead. +(communicated to MCL) + + +WARNING: it is important that the transmission and reception optimization match, so use it on both ends. + + + +
+

+ + +The following arguments define the transmission profiles. +One can use either a predefined profile, or do everything by hand, +or redefine some parameters of the predefined profiles. +These arguments must be specified at the sender and/or at the receiver, +as explained. + +

+
-p low|med|high|lan + +
+Specifies the transmission profile. +Possible values are: +low + +(low rate Internet), +med + +(mid rate Internet), +high + +(high speed Internet), and +lan + +(high speed LAN). +If not specified, the default value of MCL is used instead. +The +-p size[/rate] + +argument can be used instead (but not at the same time). +The +-plan + +profile is dedicated to LAN environments, which means that no +congestion control is used (CCI field of the LCT header left to zero, which +also means that no loss statistics are possible), +and a single ALC layer is defined. Use with care... + +The exact parameters associated to each of these four profiles +can be changed either (1) with the +-l number_of_layers + +or +-cc congestion_control_protocol + +arguments, +or (2) by modifying the src/alc/mcl_tx_prof.cpp file. +(communicated to MCL) + + +WARNING: it is important that the transmission and reception profiles match, so specify the profile on both ends. + + +
-p size[/rate] + +
+Specifies the datagram size (in bytes) (at a sender or receiver), and +optionally the transmission rate (in bits/s) (only at a sender). +This argument cannot be used along with one of the +-p low|med|high|lan + +arguments. +(communicated to MCL) + + +WARNING: it is important that the transmission and reception profiles match, so specify it on both ends (only -p size at a receiver). + + + +
-l number_of_layers + +
+Specifies the maximum number of layers to use. +If not specified, the default value of MCL is used instead. +Note that a receiver is anyway constrained by the number of layers +offered by the source. +(communicated to MCL) + + +
-cc congestion_control_protocol + +
+Specifies the congestion control protocol to use. +-cc0 + +specifies that NO CONGESTION CONTROL is used, and a single +layer is selected. +Use this mode only in appropriate environments, not over the Internet +where congestion control is mandatory. +This argument replaces the now deprecated "singlelayer" mode. +-cc1 + +specifies RLC congestion control (often needed for interoperability tests). +-cc2 + +specifies FLID-SL congestion control. This is the default, since this +protocol is less aggressive than RLC. +If nothing is specified, the default value of MCL is used instead. +(communicated to MCL) + + +
-singlelayer (DEPRECATED) + +
+This argument is DEPRECATED and replaced by the -cc0 argument, +which must be used when no congestion control is required. +
+
-P + +
+If enabled, causes fcast to make a pause before exiting (WIN32 only). +Used to prevent the closing of console window when fcast is done, thus +giving some time to read outputs. + + +
+

+ + +The following arguments are +specific to a sender. + + + +

+
-t ttl + +
+Specifies the time to live (ttl) value of the IP header. +If not specified, the default value of MCL is used instead (usually 1). +Use -t 1 if all the receivers are attached to the same LAN as the source. +(communicated to MCL) + + +
-R + +
+Enables the recursive mode. +Using this flag, fcast recursively sends the whole directory tree given as a +parameter. +At the receiver side, the same directory tree is created in the CURRENT +directory (fcast never goes upward). + +
-cont + +
+Set the +continuous mode + +for "on-demand" transmissions (i.e. receivers arrive +at their discretion, download the file and leave). +By default it is not set. +(communicated to MCL) + + +
-repeat n + +
+repeat n times the packet sequence on each layer. +Note that +-repeat 0 + +means that data is sent once. +By default, data is sent only once (no repeat) on a given layer in ``push'' +mode, and data is sent continuously in ``on-demand'' mode. +This parameter is usefull to increase the probability of good reception +at optimal speed by all receivers when working in ``push'' mode. +(communicated to MCL) + + +
-fec n + +
+Set the FEC ratio to n, a float point value greater or equal to 1.0. +This FEC ratio is the N/K ratio, of the +total number of symbols after FEC encoding (data + parity) to the +number of source symbols (data). +A default value of 2.0 is used, meaning that the number of parity +symbols is the same as the number of original source symbols. +Using +-fec 1.0 + +means that no parity packet will be produced. +(communicated to MCL) + + + +
+

+ + +The following arguments are +specific to a receiver. + + +

+
-src address + +
+Specifies the unicast IPv4 or IPv6 address or name of the source. +At a receiver <src_addr; TSI> are used to fully identify the ALC session +and to filter incoming packets. +If no +-src + +argument is provided, then any packet matching the TSI (if provided) +will be accepted with the risk they belong to other sessions +(e.g if they use the same <multicast address, port> tuple). +(communicated to MCL) + + +
-int -never or -force + +
+Sets the overwriting mode for an + +receiver when a file to save already exists. +int + +stands for interactive mode, meaning that the user will always be asked +before overwriting a file. +Using +never + +, files are never overwritten. +Finally +force + +means that any existing file will be automatically overwritten. +Default is +int + +

+mode where the answer will quickly disappear!). + + +

+

+ + +In all cases, Fcast can be aborted by typing +CTRL-C. + + + +  +

EXAMPLE

+ + +Here is a simple example where we send the file "foo.bar" +on group 225.1.2.3 (and above) : + +
+fcast -send -a225.1.2.3/2323 -v1 ./foo.bar
+
+ + +A more complex example is the following, sending the whole directory "foobar/" +in object aggregation mode for higher transmission efficiency, over a LAN: + +
+fcast -send -a225.1.2.3/2323 -demux123 -stat1 -plan -objaggr -R foobar/
+
+ + +A receiver for the previous exemple: + +
+fcast -recv -R -a225.1.2.3/2323 -demux123 -stat1 -plan -objaggr -never
+
+ + +Here is a session where we completely specify the transmission parameters +(1024 bytes of payload per packet, and 1Mbps transmission rate): + +
+fcast -send -a225.1.2.3/2323 -v1 -p1024/1000000 ./foo.bar
+fcast -recv -a225.1.2.3/2323 -v1 -p1024
+
+ + + + +  +

COPYRIGHTS

+ + +
+Copyright (c) 1999-2004 INRIA - All rights reserved
+(main authors: Vincent ROCA    - vincent.roca@inrialpes.fr
+               Julien  LABOURE - julien.laboure@inrialpes.fr
+               Christoph  NEUMANN - christoph.neumann@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ + + +  +

SEE ALSO

+ + +fcastn(1) + +for the NORM version, +mcl_ctl(3), + +MCL + +documentation, and +INRIA Research Report 5225 for an introduction to LDGM-* large block +FEC codes. + + +  +

AUTHORS

+ +
+Julien LABOURE (INRIA Rhone-Alpes, Planete project)
+Vincent ROCA (INRIA Rhone-Alpes, Planete project)
+
+ + +$Id: fcast.man.1,v 1.6 2004/12/17 11:53:12 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
OPTIONS
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/fcastn.man.1 b/man/fcastn.man.1 new file mode 100755 index 0000000..b3e6bf2 --- /dev/null +++ b/man/fcastn.man.1 @@ -0,0 +1,330 @@ +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH FCASTN "1" "" "MCLv3 Reference Manual" + +.SH NAME + +fcastn \- send or receive files using the MultiCast Library (MCL) using +the NORM protocol + +.SH SYNOPSIS + +.B fcastn +.nh +[\fB-h\fP[\fBelp\fP]] +[\fB-send\fP] +[\fB-recv\fP] +[\fB-a address\fP[\fB/port\fP]] +[\fB-if address\fP] +.\"[\fB-demux demux_level\fP] +.\"[\fB-l nb_of_layers\fP] +.\"[\fB-singlelayer\fP] +[\fB-v verbosity_level\fP] +[\fB-stat stat_level\fP] +[\fB-silent\fP] +[\fB-tmp tmp_dir_string\fP] +[\fB-p low|med|high|lan\fP] +[\fB-p size\fP[\fB/rate\fP]] +.\"[\fB-o speed/space/cpu\fP] +[\fB-P\fP] +[\fB-t ttl\fP] +[\fB-R\fP] +.\"[\fB-cont\fP] +.\"[\fB-repeat n\fP] +[\fB-fec n\fP] +.\"[\fB-huge\fP] +[\fB-src address\fP +[\fB-int\fP] +[\fB-never\fP] +[\fB-force\fP] +[\fBfile list or directory\fP] +.hy + + +.SH DESCRIPTION + +.B fcastn +is a multicast file distribution application built over the +MultiCast Library (MCL) which uses the NORM (NACK/ACK Oriented +Reliable Multicast) protocol. +.B fcastn +can run both as a sender or a receiver. +.B fcastn +has many features like the ability to send recursively all the files +of a given directory and its subdirectories but unlike +.B fcast +(which is based on the ALC reliable multicast protocol), it +cannot be used in +.B ``on-demand'' +mode, but only in +.B ``push'' +mode. +.B fcastn +communicates many meta-data information along with the files in +order to precisely re-construct the file at the receiver. +An application-level checksum (using the same algorithm as that of TCP) +is also used in order to detect possible transmission errors. + + +.SH OPTIONS + +The following arguments can be provided +.B both at a sending or receiving fcast. + +.TP +.B \-h[elp] +Gives the credits, the compilation parameters and all the possible +.B fcast +arguments. + +.TP +.B \-send or \-recv +Set the Fcast application mode to +.B sender +OR to +.B receiver. +You must ALWAYS specify one of these two modes. + +.TP +.B \-a address[/port] +Specifies the unicast or multicast IPv4 address of the base layer and its UDP +port number (if specified). +If no +.B -a +and/or +.B /port +argument is provided, then the default target address (usually that of +the loopback interface) and port number of MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port number). +.I (communicated to MCL) + +.TP +.B \-if address +The network interface to use is the one attached to the local address +specified (or hostname specified). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +.I (communicated to MCL) + +.TP +.B \-v verbosity_level +Specifies the level of verbosity desired from the MCL library. +This option also automatically enables the \-stat 2 option to +add statistics. +Note that full verbosity requires that the MCL library be compiled in +DEBUG mode. +.I (communicated to MCL) + +.TP +.B \-stat stat_level +Specifies the level of statistics desired from the MCL library. +Level 0 (default) means nothing, level 1 means that only the final +statistics (at end of session) will be displayed, level 2 means that each +time an object is fully received, statistics are displayed. +.I (communicated to MCL) + +.TP +.B \-silent +Enables the silent mode (nothing sent to stdout). + +.TP +.B \-tmp tmp_dir_string +Set the MCL temporary directory to be tmp_dir_string rather than its +default (usually "/tmp" with Unix). +The argument is a string, e.g. : +-tmp/home/roca/tmp +.I (communicated to MCL) + +.TP +.B \-p low|med|high|lan +Specifies the transmission profile. +Possible values are: +.B low +(LOW_RATE_INTERNET), +.B med +(MID_RATE_INTERNET), +.B hig +(HIGH_SPEED_INTERNET), and +.B high +(HIGH_SPEED_LAN). +If not specified, the default value of MCL is used instead. +The +.B -p size[/rate] +argument can be used instead (but not at the same time). +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception profiles match, so use it on both ends. + +.TP +.B \-p size[/rate] +Specifies the datagram size (in bytes) (at a sender or receiver), and +optionally the transmission rate (in bits/s) (only at a sender). +This argument cannot be used along with one of the +.B \-p low|med|high|lan +arguments. +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception profiles match, so use it on both ends (only -p size at a receiver). + +.TP +.B \-P +If enabled, causes fcast to make a pause before exiting (WIN32 only). +Used to prevent the closing of console window when fcast done, thus giving +some time to read outputs. + + +.PP + +The following arguments are +.B specific to a sender. + + +.TP +.B \-t ttl +Specifies the time to live (ttl) value of the IP header. +If not specified, the default value of MCL is used instead (usually 1). +Use \-t 1 if all the receivers are attached to the same LAN as the source. +.I (communicated to MCL) + +.TP +.B \-R +Enables the recursive mode. +Using this flag, fcast recursively sends the whole directory tree given as a +parameter. +At the receiver side, the same directory tree is created in the CURRENT +directory (fcast never goes upward). + +.TP +.B \-fec n +Set the FEC ratio to n. This FEC ratio is the N/K ratio, of the +total number of symbols after FEC encoding (data + FEC) to the +number of source symbols (data). +A default value of 2 is used, meaning that the same amount of FEC +symbols as original source symbols is produced. +Using +.I \-fec 1 +means that no FEC packets will be produced. +A limitation in this version is that this ratio must be an integer. +.I (communicated to MCL) + + +.PP + +The following arguments are +.B specific to a receiver. + +.TP +.B \-src address +Specifies the unicast IPv4 address or name of the source. +At a receiver are used to fully identify the ALC session +and to filter incoming packets. +If no +.B -src +argument is provided, then any packet matching the TSI (if provided) +will be accepted with the risk they belong to other sessions +(e.g if they use the same tuple). +.I (communicated to MCL) + +.TP +.B \-int \-never or \-force +Sets the overwriting mode for an +.BFcast +receiver when a file to save already exists. +.B int +stands for interactive mode, meaning that the user will always be asked +before overwriting a file. +Using +.B never +, files are never overwritten. +Finally +.B force +means that any existing file will be automatically overwritten. +Default is +.B int +. Be carefull not to forget to answer to the question (especially in verbose +mode where the answer will quickly disappear!). + + +.SH EXAMPLE + +Here is a simple example where we send the file "foo.bar" +on group 225.1.2.3 : + +.nf +fcastn -send -a225.1.2.3/2323 -v1 ./foo.bar +.fi + +A more complex example is the following, sending the whole directory "foobar/" : + +.nf +fcastn -send -a225.1.2.3/2323 -stat1 -phigh -R foobar/ +.fi + +A receiver for the previous exemple: + +.nf +fcastn -recv -R -a225.1.2.3/2323 -stat1 -phigh -never +.fi + +Here is a session where we completely specify the transmission parameters +(1024 bytes of payload per packet, and 1Mbps transmission rate): + +.nf +fcastn -send -a225.1.2.3/2323 -v1 -p1024/1000000 ./foo.bar +fcastn -recv -a225.1.2.3/2323 -v1 -p1024 +.fi + + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2002 INRIA - All rights reserved +(main authors: Vincent ROCA - vincent.roca@inrialpes.fr + Julien LABOURE - julien.laboure@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR fcast (1) +for the ALC version, +.BR mcl_ctl (3), +.BR MCL +documentation, +the INRIA Research Report 4411 (March 2002) titled +"Improving the Efficiency of a Multicast File Transfer Tool Based on ALC" + + +.SH AUTHORS +.nf +Julien LABOURE (INRIA Rhone-Alpes, Planete project) +Vincent ROCA (INRIA Rhone-Alpes, Planete project) +.fi + +$Id: fcastn.man.1,v 1.4 2004/12/17 11:53:12 roca Exp $ diff --git a/man/fcastn.man.1.html b/man/fcastn.man.1.html new file mode 100644 index 0000000..eee2495 --- /dev/null +++ b/man/fcastn.man.1.html @@ -0,0 +1,428 @@ +Content-type: text/html + +Manpage of FCASTN + +

FCASTN

+Section: Misc. Reference Manual Pages (1)
Updated:
Index +Return to Main Contents
+ + +  +

NAME

+ + +fcastn - send or receive files using the MultiCast Library (MCL) using +the NORM protocol + +  +

SYNOPSIS

+ + +fcastn + + +[-h[elp]] +[-send] +[-recv] +[-a address[/port]] +[-if address] + + + +[-v verbosity_level] +[-stat stat_level] +[-silent] +[-tmp tmp_dir_string] +[-p low|med|high|lan] +[-p size[/rate]] + +[-P] +[-t ttl] +[-R] + + +[-fec n] + +[-src address +[-int] +[-never] +[-force] +[file list or directory] + + + +  +

DESCRIPTION

+ + +fcastn + +is a multicast file distribution application built over the +MultiCast Library (MCL) which uses the NORM (NACK/ACK Oriented +Reliable Multicast) protocol. +fcastn + +can run both as a sender or a receiver. +fcastn + +has many features like the ability to send recursively all the files +of a given directory and its subdirectories but unlike +fcast + +(which is based on the ALC reliable multicast protocol), it +cannot be used in +``on-demand'' + +mode, but only in +``push'' + +mode. +fcastn + +communicates many meta-data information along with the files in +order to precisely re-construct the file at the receiver. +An application-level checksum (using the same algorithm as that of TCP) +is also used in order to detect possible transmission errors. + + +  +

OPTIONS

+ + +The following arguments can be provided +both at a sending or receiving fcast. + + +
+
-h[elp] + +
+Gives the credits, the compilation parameters and all the possible +fcast + +arguments. + +
-send or -recv + +
+Set the Fcast application mode to +sender + +OR to +receiver. + +You must ALWAYS specify one of these two modes. + +
-a address[/port] + +
+Specifies the unicast or multicast IPv4 address of the base layer and its UDP +port number (if specified). +If no +-a + +and/or +/port + +argument is provided, then the default target address (usually that of +the loopback interface) and port number of MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port number). +(communicated to MCL) + + +
-if address + +
+The network interface to use is the one attached to the local address +specified (or hostname specified). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +(communicated to MCL) + + +
-v verbosity_level + +
+Specifies the level of verbosity desired from the MCL library. +This option also automatically enables the -stat 2 option to +add statistics. +Note that full verbosity requires that the MCL library be compiled in +DEBUG mode. +(communicated to MCL) + + +
-stat stat_level + +
+Specifies the level of statistics desired from the MCL library. +Level 0 (default) means nothing, level 1 means that only the final +statistics (at end of session) will be displayed, level 2 means that each +time an object is fully received, statistics are displayed. +(communicated to MCL) + + +
-silent + +
+Enables the silent mode (nothing sent to stdout). + +
-tmp tmp_dir_string + +
+Set the MCL temporary directory to be tmp_dir_string rather than its +default (usually "/tmp" with Unix). +The argument is a string, e.g. : +-tmp/home/roca/tmp +(communicated to MCL) + + +
-p low|med|high|lan + +
+Specifies the transmission profile. +Possible values are: +low + +(LOW_RATE_INTERNET), +med + +(MID_RATE_INTERNET), +hig + +(HIGH_SPEED_INTERNET), and +high + +(HIGH_SPEED_LAN). +If not specified, the default value of MCL is used instead. +The +-p size[/rate] + +argument can be used instead (but not at the same time). +(communicated to MCL) + + +WARNING: it is important that the transmission and reception profiles match, so use it on both ends. + + +
-p size[/rate] + +
+Specifies the datagram size (in bytes) (at a sender or receiver), and +optionally the transmission rate (in bits/s) (only at a sender). +This argument cannot be used along with one of the +-p low|med|high|lan + +arguments. +(communicated to MCL) + + +WARNING: it is important that the transmission and reception profiles match, so use it on both ends (only -p size at a receiver). + + +
-P + +
+If enabled, causes fcast to make a pause before exiting (WIN32 only). +Used to prevent the closing of console window when fcast done, thus giving +some time to read outputs. + + +
+

+ + +The following arguments are +specific to a sender. + + + +

+
-t ttl + +
+Specifies the time to live (ttl) value of the IP header. +If not specified, the default value of MCL is used instead (usually 1). +Use -t 1 if all the receivers are attached to the same LAN as the source. +(communicated to MCL) + + +
-R + +
+Enables the recursive mode. +Using this flag, fcast recursively sends the whole directory tree given as a +parameter. +At the receiver side, the same directory tree is created in the CURRENT +directory (fcast never goes upward). + +
-fec n + +
+Set the FEC ratio to n. This FEC ratio is the N/K ratio, of the +total number of symbols after FEC encoding (data + FEC) to the +number of source symbols (data). +A default value of 2 is used, meaning that the same amount of FEC +symbols as original source symbols is produced. +Using +-fec 1 + +means that no FEC packets will be produced. +A limitation in this version is that this ratio must be an integer. +(communicated to MCL) + + + +
+

+ + +The following arguments are +specific to a receiver. + + +

+
-src address + +
+Specifies the unicast IPv4 address or name of the source. +At a receiver <src_addr; TSI> are used to fully identify the ALC session +and to filter incoming packets. +If no +-src + +argument is provided, then any packet matching the TSI (if provided) +will be accepted with the risk they belong to other sessions +(e.g if they use the same <multicast address, port> tuple). +(communicated to MCL) + + +
-int -never or -force + +
+Sets the overwriting mode for an + +receiver when a file to save already exists. +int + +stands for interactive mode, meaning that the user will always be asked +before overwriting a file. +Using +never + +, files are never overwritten. +Finally +force + +means that any existing file will be automatically overwritten. +Default is +int + +

+mode where the answer will quickly disappear!). + + +

+  +

EXAMPLE

+ + +Here is a simple example where we send the file "foo.bar" +on group 225.1.2.3 : + +
+fcastn -send -a225.1.2.3/2323 -v1 ./foo.bar
+
+ + +A more complex example is the following, sending the whole directory "foobar/" : + +
+fcastn -send -a225.1.2.3/2323 -stat1 -phigh -R foobar/
+
+ + +A receiver for the previous exemple: + +
+fcastn -recv -R -a225.1.2.3/2323 -stat1 -phigh -never
+
+ + +Here is a session where we completely specify the transmission parameters +(1024 bytes of payload per packet, and 1Mbps transmission rate): + +
+fcastn -send -a225.1.2.3/2323 -v1 -p1024/1000000 ./foo.bar
+fcastn -recv -a225.1.2.3/2323 -v1 -p1024
+
+ + + + +  +

COPYRIGHTS

+ + +
+Copyright (c) 1999-2002 INRIA - All rights reserved
+(main authors: Vincent ROCA    - vincent.roca@inrialpes.fr
+               Julien  LABOURE - julien.laboure@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ + + +  +

SEE ALSO

+ + +fcast(1) + +for the ALC version, +mcl_ctl(3), + +MCL + +documentation, +the INRIA Research Report 4411 (March 2002) titled +"Improving the Efficiency of a Multicast File Transfer Tool Based on ALC" + + +  +

AUTHORS

+ +
+Julien LABOURE (INRIA Rhone-Alpes, Planete project)
+Vincent ROCA (INRIA Rhone-Alpes, Planete project)
+
+ + +$Id: fcastn.man.1,v 1.4 2004/12/17 11:53:12 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
OPTIONS
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/flute.man.1 b/man/flute.man.1 new file mode 100755 index 0000000..6c44b31 --- /dev/null +++ b/man/flute.man.1 @@ -0,0 +1,511 @@ +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH FLUTE "1" "" "MCLv3 Reference Manual" + +.SH NAME + +flute \- send or receive files, as specified in FLUTE (RFC 3926) and using +the ALC transport protocol (RFC 3452). + +.SH SYNOPSIS + +.B flute +.nh +[\fB-h\fP[\fBelp\fP]] +[\fB-send\fP] +[\fB-recv\fP] +[\fB-a address\fP[\fB/port\fP]] +[\fB-ifa address\fP] +[\fB-ifn ifname\fP] +[\fB-demux demux_level\fP] +[\fB-v verbosity_level\fP] +[\fB-stat stat_level\fP] +[\fB-silent\fP] +[\fB-tmp tmp_dir_string\fP] +.\" [\fB-objaggr\fP] +[\fB-o speed/space/cpu\fP] +[\fB-p low|med|high|lan\fP] +[\fB-p size\fP[\fB/rate\fP]] +[\fB-l nb_of_layers\fP] +[\fB-cc congestion_control_protocol\fP] +[\fB-P\fP] +[\fB-t ttl\fP] +[\fB-R\fP] +[\fB-cont\fP] +[\fB-repeat n\fP] +[\fB-fec n\fP] +.\" [\fB-huge (DEPRECATED)\fP] +[\fB-src address\fP +[\fB-int\fP] +[\fBfile or directory\fP] +.hy + +.PP +At a sender: +.nf +.B flute -send [options] file +.fi +.nf +.B flute -send [options] -R directory +.fi + +.PP +At a receiver: +.nf +.B flute -recv [options] +.fi + + +.SH DESCRIPTION + +.B flute +is a multicast file distribution application built over the +MultiCast Library (MCLv3) which uses the ALC (Asynchronous +Layered Coding) reliable multicast protocol. +.B flute +can run both as a sender or a receiver. +.B flute +has many features like the ability to send recursively all the files +of a given directory and its subdirectories, and the possibility to be used +in +.B ``on-demand'' +or +.B ``push'' +mode. +.B flute +communicates many meta-data information along with the files in +associated File Delivery Tables (FDT), in order to let the receiver +choose what files he wants to receive. +An application-level MD5 checksum is also used in order to detect +possible transmission errors. + +.B fcast +and +.B flute +differ from the fact that the first one uses private, non standard, +solutions, while the second one strictly follows IETF standards. +.B fcast +is appropriate when looking for a simple yet efficient tool, while +.B flute +is appropriate when using IETF standardized solutions is mandatory, or +when a large set of files are sent within a session and receivers +may be interested only in a subset of them. +.B flute +filtering mechanism is in that case a real asset. +The two tools are otherwise sharing many similarities, as well +as most arguments. + + +.SH OPTIONS + +The following arguments can be provided +.B both at a sending or receiving flute. + +.TP +.B \-h[elp] +Gives the credits, the compilation parameters and all the possible +.B flute +arguments. + +.TP +.B \-send or \-recv +Set the Fcast application mode to +.B sender +OR to +.B receiver. +You must ALWAYS specify one of these two modes. + +.TP +.B \-a address[/port] +Specifies the unicast or multicast IPv4 or IPv6 address of the base layer and its UDP +port number (if specified). +If no +.B -a +and/or +.B /port +argument is provided, then the default target address (usually that of +the loopback interface) and port number of MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port number). +.I (communicated to MCL) + +.TP +.B \-ifa address +The network interface to use is the one attached to the local address +specified (or hostname specified). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +The alternative is to use +.B \-ifn ifname. +.I (communicated to MCL) + +.TP +.B \-ifn ifname +The network interface to use is the one attached to the name +specified (e.g. +.B \-ifneth0 +). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +The alternative is to use +.B \-ifa address. +.I (communicated to MCL) + +.TP +.B \-demux N +Sets the LCT Transport Session Identifier (or TSI) to +.B N. +At a sender this TSI is included in each packet sent. +At a receiver are used to fully identify the ALC session +and to filter incoming packets. +If no +.B -demux +argument is provided, then any packet matching the source address (if +provided) will be accepted with the risk they belong to other sessions +(e.g if they use the same tuple). +This demux label is also usefull to make sure that the current session will +not get confused by packets from previous incarnation session. +The receivers and the sender must of course agree beforehand and use the +same value. +By default a value of 0 is used. +.I (communicated to MCL) + +.B \-v verbosity_level +Specifies the level of verbosity desired from the MCL library. +This option also automatically enables the \-stat 2 option to +add statistics. +Note that full verbosity requires that the MCL library be compiled in +DEBUG mode. +.I (communicated to MCL) + +.TP +.B \-stat stat_level +Specifies the level of statistics desired from the MCL library. +Level 0 (default) means nothing, level 1 means that only the final +statistics (at end of session) will be displayed, level 2 means that each +time an object is fully received, statistics are displayed. +.I (communicated to MCL) + +.TP +.B \-silent +Enables the silent mode (nothing is sent to stdout). + +.TP +.B \-tmp tmp_dir_string +Set the MCL temporary directory to be tmp_dir_string rather than its +default (usually "/tmp" with Unix). +The argument is a string, e.g. : +-tmp/home/roca/tmp +.I (communicated to MCL) + +.TP +.B \-objaggr +Enables the object aggregation mode. +This mode is highly efficient when sending a large number of small objects +(i.e. files) since FEC encoding now operates on the large object (that is the +result of the aggregation of all the small objects), rather than on +each small object. +Transmissions are an order of magnitude more efficient. +This solution is similar in spirit to the one described in +. +This mode requires that the recursive mode is set (to transmit several files). +.I (communicated to MCL) + +.TP +.B \-o space/speed/cpu +Specifies the optimization profile (in particular the order in which packets +are sent on each layer). +Possible values are: +.B space +to optimize the maximum memory space required at a receiver, +.B speed +to optimize the reception speed, and +.B cpu +to differ CPU intensive tasks at a receiver (recommanded on a +CPU bounded host). +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception optimization match, so use it on both ends. + + +.PP + +The following arguments define the transmission profiles. +One can use either a predefined profile, or do everything by hand, +or redefine some parameters of the predefined profiles. +These arguments must be specified at the sender and/or at the receiver, +as explained. + +.TP +.B \-p low|med|high|lan +Specifies the transmission profile. +Possible values are: +.B low +(low rate Internet), +.B med +(mid rate Internet), +.B high +(high speed Internet), and +.B lan +(high speed LAN). +If not specified, the default value of MCL is used instead. +The +.B -p size[/rate] +argument can be used instead (but not at the same time). +The +.B -plan +profile is dedicated to LAN environments, which means that no +congestion control is used (CCI field of the LCT header left to zero, which +also means that no loss statistics are possible), +and a single ALC layer is defined. Use with care... + +The exact parameters associated to each of these four profiles +can be changed either (1) with the +.B -p size[/rate] +or +.B -l number_of_layers +or +.B -cc congestion_control_protocol +arguments, +or (2) by modifying the src/alc/mcl_tx_prof.cpp file. +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception profiles match, so specify the profile on both ends. + +.TP +.B \-p size[/rate] +Specifies the datagram size (in bytes) (at a sender or receiver), and +optionally the transmission rate (in bits/s) (only at a sender). +This argument cannot be used along with one of the +.B \-p low|med|high|lan +arguments. +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception profiles match, so specify it on both ends (only -p size at a receiver). + + +.TP +.B \-l number_of_layers +Specifies the maximum number of layers to use. +If not specified, the default value of MCL is used instead. +Note that a receiver is anyway constrained by the number of layers +offered by the source. +.I (communicated to MCL) + +.TP +.B \-cc congestion_control_protocol +Specifies the congestion control protocol to use. +.B -cc0 +specifies that NO CONGESTION CONTROL is used, and a single +layer is selected. +Use this mode only in appropriate environments, not over the Internet +where congestion control is mandatory. +This argument replaces the now deprecated "singlelayer" mode. +.B -cc1 +specifies RLC congestion control (often needed for interoperability tests). +.B -cc2 +specifies FLID-SL congestion control. This is the default, since this +protocol is less aggressive than RLC. +If nothing is specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.TP +.B \-singlelayer (DEPRECATED) +This argument is DEPRECATED and replaced by the -cc0 argument, +which must be used when no congestion control is required. +.TP + +.TP +.B \-P +If enabled, causes flute to make a pause before exiting (WIN32 only). +Used to prevent the closing of console window when flute is done, thus +giving some time to read outputs. + + +.PP + +The following arguments are +.B specific to a sender. + + +.TP +.B \-t ttl +Specifies the time to live (ttl) value of the IP header. +If not specified, the default value of MCL is used instead (usually 1). +Use \-t 1 if all the receivers are attached to the same LAN as the source. +.I (communicated to MCL) + +.TP +.B \-R +Enables the recursive mode. +Using this flag, flute recursively sends the whole directory tree given as a +parameter. +At the receiver side, the same directory tree is created in the CURRENT +directory (flute never goes upward). + +.TP +.B \-cont +Set the +.I continuous mode +for "on-demand" transmissions (i.e. receivers arrive +at their discretion, download the file and leave). +By default it is not set. +.I (communicated to MCL) + +.TP +.B \-repeat n +repeat n times the packet sequence on each layer. +Note that +.I \-repeat 0 +means that data is sent once. +By default, data is sent only once (no repeat) on a given layer in ``push'' +mode, and data is sent continuously in ``on-demand'' mode. +This parameter is usefull to increase the probability of good reception +at optimal speed by all receivers when working in ``push'' mode. +.I (communicated to MCL) + +.TP +.B \-fec n +Set the FEC ratio to n, a float point value greater or equal to 1.0. +This FEC ratio is the N/K ratio, of the +total number of symbols after FEC encoding (data + parity) to the +number of source symbols (data). +A default value of 2.0 is used, meaning that the number of parity +symbols is the same as the number of original source symbols. +Using +.I \-fec 1.0 +means that no parity packet will be produced. +.I (communicated to MCL) + + +.PP + +The following arguments are +.B specific to a receiver. + +.TP +.B \-src address +Specifies the unicast IPv4 or IPv6 address or name of the source. +At a receiver are used to fully identify the ALC session +and to filter incoming packets. +If no +.B -src +argument is provided, then any packet matching the TSI (if provided) +will be accepted with the risk they belong to other sessions +(e.g if they use the same tuple). +.I (communicated to MCL) + +.TP +.B \-int \-never or \-force +Sets the overwriting mode for an +.BFcast +receiver when a file to save already exists. +.B int +stands for interactive mode, meaning that the user will always be asked +before overwriting a file. +Using +.B never +, files are never overwritten. +Finally +.B force +means that any existing file will be automatically overwritten. +Default is +.B int +. Be carefull not to forget to answer to the question (especially in verbose +mode where the answer will quickly disappear!). + + +.PP + +In all cases, Fcast can be aborted by typing +.B CTRL\-C. + + +.SH EXAMPLE + +Here is a simple example where we send the file "foo.bar" +on group 225.1.2.3 (and above) : + +.nf +flute -send -a225.1.2.3/2323 -v1 ./foo.bar +.fi + +A more complex example is the following, sending the whole directory "foobar/" +in object aggregation mode for higher transmission efficiency, over a LAN: + +.nf +flute -send -a225.1.2.3/2323 -demux123 -stat1 -plan -objaggr -R foobar/ +.fi + +A receiver for the previous exemple: + +.nf +flute -recv -R -a225.1.2.3/2323 -demux123 -stat1 -plan -objaggr -never +.fi + +Here is a session where we completely specify the transmission parameters +(1024 bytes of payload per packet, and 1Mbps transmission rate): + +.nf +flute -send -a225.1.2.3/2323 -v1 -p1024/1000000 ./foo.bar +flute -recv -a225.1.2.3/2323 -v1 -p1024 +.fi + + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2004 INRIA - All rights reserved +(main authors: Vincent ROCA - vincent.roca@inrialpes.fr + Julien LABOURE - julien.laboure@inrialpes.fr + Christoph NEUMANN - christoph.neumann@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR fcast (1) +.BR mcl_ctl (3), +.BR MCL +documentation, +INRIA Research Report 5225 for an introduction to LDGM-* large block +FEC codes, +RFC 3926 (FLUTE), and . + + + +.SH AUTHORS +.nf +Christoph NEUMANN (INRIA Rhone-Alpes, Planete project) +Vincent ROCA (INRIA Rhone-Alpes, Planete project) +Julien LABOURE (INRIA Rhone-Alpes, Planete project) +.fi + +$Id: flute.man.1,v 1.2 2004/12/21 16:27:34 roca Exp $ diff --git a/man/flute.man.1.html b/man/flute.man.1.html new file mode 100644 index 0000000..55d3b60 --- /dev/null +++ b/man/flute.man.1.html @@ -0,0 +1,657 @@ +Content-type: text/html + +Manpage of FLUTE + +

FLUTE

+Section: Misc. Reference Manual Pages (1)
Updated:
Index +Return to Main Contents
+ + +  +

NAME

+ + +flute - send or receive files, as specified in FLUTE (RFC 3926) and using +the ALC transport protocol (RFC 3452). + +  +

SYNOPSIS

+ + +flute + + +[-h[elp]] +[-send] +[-recv] +[-a address[/port]] +[-ifa address] +[-ifn ifname] +[-demux demux_level] +[-v verbosity_level] +[-stat stat_level] +[-silent] +[-tmp tmp_dir_string] + +[-o speed/space/cpu] +[-p low|med|high|lan] +[-p size[/rate]] +[-l nb_of_layers] +[-cc congestion_control_protocol] +[-P] +[-t ttl] +[-R] +[-cont] +[-repeat n] +[-fec n] + +[-src address +[-int] +[file or directory] + + +

+ +At a sender: +

+flute -send [options] file
+
+ +
+flute -send [options] -R directory
+
+ + +

+ +At a receiver: +

+flute -recv [options]
+
+ + + +  +

DESCRIPTION

+ + +flute + +is a multicast file distribution application built over the +MultiCast Library (MCLv3) which uses the ALC (Asynchronous +Layered Coding) reliable multicast protocol. +flute + +can run both as a sender or a receiver. +flute + +has many features like the ability to send recursively all the files +of a given directory and its subdirectories, and the possibility to be used +in +``on-demand'' + +or +``push'' + +mode. +flute + +communicates many meta-data information along with the files in +associated File Delivery Tables (FDT), in order to let the receiver +choose what files he wants to receive. +An application-level MD5 checksum is also used in order to detect +possible transmission errors. + +fcast + +and +flute + +differ from the fact that the first one uses private, non standard, +solutions, while the second one strictly follows IETF standards. +fcast + +is appropriate when looking for a simple yet efficient tool, while +flute + +is appropriate when using IETF standardized solutions is mandatory, or +when a large set of files are sent within a session and receivers +may be interested only in a subset of them. +flute + +filtering mechanism is in that case a real asset. +The two tools are otherwise sharing many similarities, as well +as most arguments. + + +  +

OPTIONS

+ + +The following arguments can be provided +both at a sending or receiving flute. + + +
+
-h[elp] + +
+Gives the credits, the compilation parameters and all the possible +flute + +arguments. + +
-send or -recv + +
+Set the Fcast application mode to +sender + +OR to +receiver. + +You must ALWAYS specify one of these two modes. + +
-a address[/port] + +
+Specifies the unicast or multicast IPv4 or IPv6 address of the base layer and its UDP +port number (if specified). +If no +-a + +and/or +/port + +argument is provided, then the default target address (usually that of +the loopback interface) and port number of MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port number). +(communicated to MCL) + + +
-ifa address + +
+The network interface to use is the one attached to the local address +specified (or hostname specified). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +The alternative is to use +-ifn ifname. + +(communicated to MCL) + + +
-ifn ifname + +
+The network interface to use is the one attached to the name +specified (e.g. +-ifneth0 + +). +This option is only required on multi-homed hosts or on routers as the +default interface chosen by the system without this option to send/receive +multicast may not be the one you want to use. +The alternative is to use +-ifa address. + +(communicated to MCL) + + +
-demux N + +
+Sets the LCT Transport Session Identifier (or TSI) to +N. + +At a sender this TSI is included in each packet sent. +At a receiver <src_addr; TSI> are used to fully identify the ALC session +and to filter incoming packets. +If no +-demux + +argument is provided, then any packet matching the source address (if +provided) will be accepted with the risk they belong to other sessions +(e.g if they use the same <multicast address, port> tuple). +This demux label is also usefull to make sure that the current session will +not get confused by packets from previous incarnation session. +The receivers and the sender must of course agree beforehand and use the +same value. +By default a value of 0 is used. +(communicated to MCL) + + +-v verbosity_level + +Specifies the level of verbosity desired from the MCL library. +This option also automatically enables the -stat 2 option to +add statistics. +Note that full verbosity requires that the MCL library be compiled in +DEBUG mode. +(communicated to MCL) + + +
-stat stat_level + +
+Specifies the level of statistics desired from the MCL library. +Level 0 (default) means nothing, level 1 means that only the final +statistics (at end of session) will be displayed, level 2 means that each +time an object is fully received, statistics are displayed. +(communicated to MCL) + + +
-silent + +
+Enables the silent mode (nothing is sent to stdout). + +
-tmp tmp_dir_string + +
+Set the MCL temporary directory to be tmp_dir_string rather than its +default (usually "/tmp" with Unix). +The argument is a string, e.g. : +-tmp/home/roca/tmp +(communicated to MCL) + + +
-objaggr + +
+Enables the object aggregation mode. +This mode is highly efficient when sending a large number of small objects +(i.e. files) since FEC encoding now operates on the large object (that is the +result of the aggregation of all the small objects), rather than on +each small object. +Transmissions are an order of magnitude more efficient. +This solution is similar in spirit to the one described in +<draft-neumann-rmt-flute-file-aggregation-00.txt>. +This mode requires that the recursive mode is set (to transmit several files). +(communicated to MCL) + + +
-o space/speed/cpu + +
+Specifies the optimization profile (in particular the order in which packets +are sent on each layer). +Possible values are: +space + +to optimize the maximum memory space required at a receiver, +speed + +to optimize the reception speed, and +cpu + +to differ CPU intensive tasks at a receiver (recommanded on a +CPU bounded host). +If not specified, the default value of MCL is used instead. +(communicated to MCL) + + +WARNING: it is important that the transmission and reception optimization match, so use it on both ends. + + + +
+

+ + +The following arguments define the transmission profiles. +One can use either a predefined profile, or do everything by hand, +or redefine some parameters of the predefined profiles. +These arguments must be specified at the sender and/or at the receiver, +as explained. + +

+
-p low|med|high|lan + +
+Specifies the transmission profile. +Possible values are: +low + +(low rate Internet), +med + +(mid rate Internet), +high + +(high speed Internet), and +lan + +(high speed LAN). +If not specified, the default value of MCL is used instead. +The +-p size[/rate] + +argument can be used instead (but not at the same time). +The +-plan + +profile is dedicated to LAN environments, which means that no +congestion control is used (CCI field of the LCT header left to zero, which +also means that no loss statistics are possible), +and a single ALC layer is defined. Use with care... + +The exact parameters associated to each of these four profiles +can be changed either (1) with the +-p size[/rate] + +or +-l number_of_layers + +or +-cc congestion_control_protocol + +arguments, +or (2) by modifying the src/alc/mcl_tx_prof.cpp file. +(communicated to MCL) + + +WARNING: it is important that the transmission and reception profiles match, so specify the profile on both ends. + + +
-p size[/rate] + +
+Specifies the datagram size (in bytes) (at a sender or receiver), and +optionally the transmission rate (in bits/s) (only at a sender). +This argument cannot be used along with one of the +-p low|med|high|lan + +arguments. +(communicated to MCL) + + +WARNING: it is important that the transmission and reception profiles match, so specify it on both ends (only -p size at a receiver). + + + +
-l number_of_layers + +
+Specifies the maximum number of layers to use. +If not specified, the default value of MCL is used instead. +Note that a receiver is anyway constrained by the number of layers +offered by the source. +(communicated to MCL) + + +
-cc congestion_control_protocol + +
+Specifies the congestion control protocol to use. +-cc0 + +specifies that NO CONGESTION CONTROL is used, and a single +layer is selected. +Use this mode only in appropriate environments, not over the Internet +where congestion control is mandatory. +This argument replaces the now deprecated "singlelayer" mode. +-cc1 + +specifies RLC congestion control (often needed for interoperability tests). +-cc2 + +specifies FLID-SL congestion control. This is the default, since this +protocol is less aggressive than RLC. +If nothing is specified, the default value of MCL is used instead. +(communicated to MCL) + + +
-singlelayer (DEPRECATED) + +
+This argument is DEPRECATED and replaced by the -cc0 argument, +which must be used when no congestion control is required. +
+
-P + +
+If enabled, causes flute to make a pause before exiting (WIN32 only). +Used to prevent the closing of console window when flute is done, thus +giving some time to read outputs. + + +
+

+ + +The following arguments are +specific to a sender. + + + +

+
-t ttl + +
+Specifies the time to live (ttl) value of the IP header. +If not specified, the default value of MCL is used instead (usually 1). +Use -t 1 if all the receivers are attached to the same LAN as the source. +(communicated to MCL) + + +
-R + +
+Enables the recursive mode. +Using this flag, flute recursively sends the whole directory tree given as a +parameter. +At the receiver side, the same directory tree is created in the CURRENT +directory (flute never goes upward). + +
-cont + +
+Set the +continuous mode + +for "on-demand" transmissions (i.e. receivers arrive +at their discretion, download the file and leave). +By default it is not set. +(communicated to MCL) + + +
-repeat n + +
+repeat n times the packet sequence on each layer. +Note that +-repeat 0 + +means that data is sent once. +By default, data is sent only once (no repeat) on a given layer in ``push'' +mode, and data is sent continuously in ``on-demand'' mode. +This parameter is usefull to increase the probability of good reception +at optimal speed by all receivers when working in ``push'' mode. +(communicated to MCL) + + +
-fec n + +
+Set the FEC ratio to n, a float point value greater or equal to 1.0. +This FEC ratio is the N/K ratio, of the +total number of symbols after FEC encoding (data + parity) to the +number of source symbols (data). +A default value of 2.0 is used, meaning that the number of parity +symbols is the same as the number of original source symbols. +Using +-fec 1.0 + +means that no parity packet will be produced. +(communicated to MCL) + + + +
+

+ + +The following arguments are +specific to a receiver. + + +

+
-src address + +
+Specifies the unicast IPv4 or IPv6 address or name of the source. +At a receiver <src_addr; TSI> are used to fully identify the ALC session +and to filter incoming packets. +If no +-src + +argument is provided, then any packet matching the TSI (if provided) +will be accepted with the risk they belong to other sessions +(e.g if they use the same <multicast address, port> tuple). +(communicated to MCL) + + +
-int -never or -force + +
+Sets the overwriting mode for an + +receiver when a file to save already exists. +int + +stands for interactive mode, meaning that the user will always be asked +before overwriting a file. +Using +never + +, files are never overwritten. +Finally +force + +means that any existing file will be automatically overwritten. +Default is +int + +

+mode where the answer will quickly disappear!). + + +

+

+ + +In all cases, Fcast can be aborted by typing +CTRL-C. + + + +  +

EXAMPLE

+ + +Here is a simple example where we send the file "foo.bar" +on group 225.1.2.3 (and above) : + +
+flute -send -a225.1.2.3/2323 -v1 ./foo.bar
+
+ + +A more complex example is the following, sending the whole directory "foobar/" +in object aggregation mode for higher transmission efficiency, over a LAN: + +
+flute -send -a225.1.2.3/2323 -demux123 -stat1 -plan -objaggr -R foobar/
+
+ + +A receiver for the previous exemple: + +
+flute -recv -R -a225.1.2.3/2323 -demux123 -stat1 -plan -objaggr -never
+
+ + +Here is a session where we completely specify the transmission parameters +(1024 bytes of payload per packet, and 1Mbps transmission rate): + +
+flute -send -a225.1.2.3/2323 -v1 -p1024/1000000 ./foo.bar
+flute -recv -a225.1.2.3/2323 -v1 -p1024
+
+ + + + +  +

COPYRIGHTS

+ + +
+Copyright (c) 1999-2004 INRIA - All rights reserved
+(main authors: Vincent ROCA    - vincent.roca@inrialpes.fr
+               Julien  LABOURE - julien.laboure@inrialpes.fr
+               Christoph  NEUMANN - christoph.neumann@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ + + +  +

SEE ALSO

+ + +fcast(1) + +mcl_ctl(3), + +MCL + +documentation, +INRIA Research Report 5225 for an introduction to LDGM-* large block +FEC codes, +RFC 3926 (FLUTE), and <draft-neumann-rmt-flute-file-aggregation-00.txt>. + + + +  +

AUTHORS

+ +
+Christoph NEUMANN (INRIA Rhone-Alpes, Planete project)
+Vincent ROCA (INRIA Rhone-Alpes, Planete project)
+Julien LABOURE (INRIA Rhone-Alpes, Planete project)
+
+ + +$Id: flute.man.1,v 1.2 2004/12/21 16:27:34 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
OPTIONS
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/mcl_abort.man.3 b/man/mcl_abort.man.3 new file mode 100644 index 0000000..daf749b --- /dev/null +++ b/man/mcl_abort.man.3 @@ -0,0 +1,92 @@ +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH MCL_ABORT "3" "" "MCLv3 Reference Manual" + + +.SH NAME + +mcl_abort \- abort an ongoing MCL (MultiCast Library) session + + +.SH SYNOPSIS + +.sp +\fB #include "../src/common/mcl_lib_api.h"\fI + +\fB int mcl_abort (int \fIid\fB);\fI +.fi + +.SH DESCRIPTION + +Aborts (i.e. closes immediately and non-gracefully) an MCL session. +This call +.B returns immediately. +This function is typically called when the upper application catches +a SIGINT or SIGKILL signal with its signal handler function. +Calling +.I mcl_abort() +with an identifier that does not refer to an MCL session leads MCL +to return immediately. + + +.SH RETURN VALUE + +Returns 0 on success, a negative (< 0) value in case of error. + + +.SH EXAMPLE + +Here is a simple example to close an MCL session as a source. + +.nf + int id; + + if (mcl_abort(id) < 0) { + printf("ERROR: mcl_abort failed"); + exit(-1); + } +.fi + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2003 INRIA - Universite Paris 6 - +All rights reserved +(main author: Vincent Roca - vincent.roca@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR MCL +documentation + + +.SH AUTHORS + +Vincent Roca (INRIA Rhone-Alpes, Planete project) + +$Id: mcl_abort.man.3,v 1.2 2003/11/28 10:05:30 roca Exp $ diff --git a/man/mcl_abort.man.3.html b/man/mcl_abort.man.3.html new file mode 100644 index 0000000..8c158e2 --- /dev/null +++ b/man/mcl_abort.man.3.html @@ -0,0 +1,122 @@ +Content-type: text/html + +Manpage of MCL_ABORT + +

MCL_ABORT

+Section: Misc. Reference Manual Pages (3)
Updated:
Index +Return to Main Contents
+ +

+

+  +

NAME

+ +

+mcl_abort - abort an ongoing MCL (MultiCast Library) session +

+

+  +

SYNOPSIS

+ +

+

+ #include "../src/common/mcl_lib_api.h" +

+ int mcl_abort (int id); + +

+  +

DESCRIPTION

+ +

+Aborts (i.e. closes immediately and non-gracefully) an MCL session. +This call +returns immediately. + +This function is typically called when the upper application catches +a SIGINT or SIGKILL signal with its signal handler function. +Calling +mcl_abort() + +with an identifier that does not refer to an MCL session leads MCL +to return immediately. +

+

+  +

RETURN VALUE

+ +

+Returns 0 on success, a negative (< 0) value in case of error. +

+

+  +

EXAMPLE

+ +

+Here is a simple example to close an MCL session as a source. +

+

+        int     id;
+
+        if (mcl_abort(id) < 0) {
+                printf("ERROR: mcl_abort failed");
+                exit(-1);
+        }
+
+ +

+

+  +

COPYRIGHTS

+ +

+

+Copyright (c) 1999-2003 INRIA - Universite Paris 6 -
+All rights reserved
+(main author: Vincent Roca - vincent.roca@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ +

+

+  +

SEE ALSO

+ +

+MCL + +documentation +

+

+  +

AUTHORS

+ +

+Vincent Roca (INRIA Rhone-Alpes, Planete project) +

+$Id: mcl_abort.man.3,v 1.2 2003/11/28 10:05:30 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
RETURN VALUE
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/mcl_close.man.3 b/man/mcl_close.man.3 new file mode 100644 index 0000000..1021d9f --- /dev/null +++ b/man/mcl_close.man.3 @@ -0,0 +1,96 @@ +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH MCL_CLOSE "3" "" "MCLv3 Reference Manual" + + +.SH NAME + +mcl_close \- close an MCL (MultiCast Library) session + + +.SH SYNOPSIS + +.sp +\fB #include "../src/common/mcl_lib_api.h"\fI + +\fB int mcl_close (int \fIid\fB);\fI +.fi + +.SH DESCRIPTION + +Closes an MCL session. +This call is +.B blocking (i.e. synchronous) on the sending side +to let it send all the data that has not yet been sent. +This call +.B returns immediately on the receiving side. + +Calling +.I mcl_close() +with an identifier that does not refer to an MCL session leads to calling the +.I close() +system call with that identifier. + + + +.SH RETURN VALUE + +Returns 0 on success, a negative (< 0) value in case of error. + + +.SH EXAMPLE + +Here is a simple example to close an MCL session as a source. + +.nf + int id; + + if (mcl_close(id) < 0) { + printf("ERROR: mcl_close failed"); + exit(-1); + } +.fi + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2003 INRIA - Universite Paris 6 - +All rights reserved +(main author: Vincent Roca - vincent.roca@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR MCL +documentation + + +.SH AUTHORS + +Vincent Roca (INRIA Rhone-Alpes, Planete project) + +$Id: mcl_close.man.3,v 1.2 2003/11/28 10:05:30 roca Exp $ diff --git a/man/mcl_close.man.3.html b/man/mcl_close.man.3.html new file mode 100644 index 0000000..b2f4e62 --- /dev/null +++ b/man/mcl_close.man.3.html @@ -0,0 +1,128 @@ +Content-type: text/html + +Manpage of MCL_CLOSE + +

MCL_CLOSE

+Section: Misc. Reference Manual Pages (3)
Updated:
Index +Return to Main Contents
+ +

+

+  +

NAME

+ +

+mcl_close - close an MCL (MultiCast Library) session +

+

+  +

SYNOPSIS

+ +

+

+ #include "../src/common/mcl_lib_api.h" +

+ int mcl_close (int id); + +

+  +

DESCRIPTION

+ +

+Closes an MCL session. +This call is +blocking (i.e. synchronous) on the sending side + +to let it send all the data that has not yet been sent. +This call +returns immediately on the receiving side. + +

+Calling +mcl_close() + +with an identifier that does not refer to an MCL session leads to calling the +close() + +system call with that identifier. +

+

+

+  +

RETURN VALUE

+ +

+Returns 0 on success, a negative (< 0) value in case of error. +

+

+  +

EXAMPLE

+ +

+Here is a simple example to close an MCL session as a source. +

+

+        int     id;
+
+        if (mcl_close(id) < 0) {
+                printf("ERROR: mcl_close failed");
+                exit(-1);
+        }
+
+ +

+

+  +

COPYRIGHTS

+ +

+

+Copyright (c) 1999-2003 INRIA - Universite Paris 6 -
+All rights reserved
+(main author: Vincent Roca - vincent.roca@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ +

+

+  +

SEE ALSO

+ +

+MCL + +documentation +

+

+  +

AUTHORS

+ +

+Vincent Roca (INRIA Rhone-Alpes, Planete project) +

+$Id: mcl_close.man.3,v 1.2 2003/11/28 10:05:30 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
RETURN VALUE
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/mcl_ctl.man.3 b/man/mcl_ctl.man.3 new file mode 100644 index 0000000..041530a --- /dev/null +++ b/man/mcl_ctl.man.3 @@ -0,0 +1,444 @@ +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH MCL_CTL "3" "" "MCLv3 Reference Manual" + +.SH NAME + +mcl_ctl \- control function of the MultiCast Library (MCL) + + +.SH SYNOPSIS + +.sp +\fB #include "../src/common/mcl_lib_api.h"\fI + +\fB int mcl_ctl (int \fIid\fB, int \fIoptname\fB, void* \fIoptvalue\fB, int \fIoptlen\fB);\fI + +.fi + +.SH DESCRIPTION + +.B mcl_ctl +is meant to control all the internal options of the MCL library +and to offer the possibility to override default values. +Most of these options only apply to the current session (identified +by the +.B id +identifier). + +The arguments are: + +.TP +.B int id +session identifier returned by +.B mcl_open +.TP +.B int optname +option name +.TP +.B void* optvalue +pointer to the value area. Depending on the option, this value can +be provided to MCL (to set an option), or be modified and returned by MCL +(to read the current value of an option). +.TP +.B int optlen +length of the value area. +.PP + +The following options are defined: + +.TP +.I MCL_OPT_LAYER_NB: +maximum number of layers used by a traffic source or a receiver (it depends +on the congestion flow control module). + +Argument: int + +.TP +.I MCL_OPT_SINGLE_LAYER: +This argument optimizes transmissions for the single layer, fixed rate, +no congestion-control case. + +Argument: int (0 or 1) + + +.TP +.I MCL_OPT_PORT: +UDP port number in host order. +Another way to specify the port number is to use MCL_OPT_BIND option. + +Argument: int (and not a short!) + +.TP +.I MCL_OPT_ADDR: +Another way to specify the address is to use MCL_OPT_BIND option. +IPv4 address in host order. + +Argument: int + +.TP +.I MCL_OPT_BIND: +This is an alternative to the +.I MCL_OPT_PORT +and +.I MCL_OPT_ADDR +options. +It's use is exactly the same as that of the Socket +.I bind() +system call. +The struct sockaddr supplied is in network order (use hton functions first). + +Argument: struct sockaddr + +.TP +.I MCL_OPT_DEMUX_LABEL: +Specify the demultiplexing label to use on that session, also called +Transport Session Identifier (TSI) in the ALC/LCT drafts. + +Argument: int + +.TP +.I MCL_OPT_TTL: +IP Time To Live (TTL) value. This parameters controls the scope of unicast +and multicast packets generated by the traffic source. +Use with care as large values of TTL can easily lead to flooding the whole +MBONE. + +Argument: int + +.TP +.I MCL_OPT_STATS: +Controls the print of statistics during transmissions. +A value of 0 will avoid any print (but statistics are anyway gathered), +1 will lead to print major statistics (e.g. at the end of reception), +and 2 will lead to print statistics regularly. + +Argument: int + +.TP +.I MCL_OPT_VERBOSITY: +This option is only usefull if the MCL library has been compiled with the +DEBUG flag. +It controls the level of verbosity desired. +It can range from 0 (quiet mode, the default), to 6 (full verbosity, +with a message each time an MCL internal function is called). +Usefull for debug and to know what's going on... +A value of 2 is required to collect major events and do post analysis +of a session using the tools in the "test" directory. + +Argument: int + +.TP +.I MCL_OPT_MOREABOUT: +Get release information, compilation flags and credits. + +Argument: none + +.TP +.I MCL_OPT_TMP_DIR: +Specify the directory to use for temporary files +(e.g. for the virtual transmission memory service). + +Argument: null terminated string (give the strlen() of this string in +the optlen argument) + +.TP +.I MCL_OPT_NETIF: +Network interface, in host order, to use. +Only usefull in case of multi-homed hosts or routers. + +Argument: int + +.TP +.I MCL_OPT_LOOPBACK: +Should receivers on the same host as the source also receive data? +(by default yes). +Rarely usefull! + +Argument: int + +.PP +Source specific options: + + +.TP +.I MCL_OPT_DELIVERY_MODE: +Used by the traffic source (only) to specify the delivery mode. +Currently, this mode can be +.I DEL_MODE_PUSH +for transmissions in ``push'' mode (i.e. data is sent once, all +the receivers must be ready) and +.I DEL_MODE_ON_DEMAND +for transmissions in ``on-demand'' mode (i.e. data is sent continuously +in cycles, receivers can arrive at any time, get data and leave). + +Argument: int ( +.I DEL_MODE_PUSH +or +.I DEL_MODE_ON_DEMAND +) + +.TP +.I MCL_OPT_TX_PROFILE: +Select a predefined transmission profile. +Currently this profile can be one of +.I MCL_TX_PROFILE_LOW_RATE_INTERNET +, +.I MCL_TX_PROFILE_MID_RATE_INTERNET +, or +.I MCL_TX_PROFILE_HIGH_SPEED_LAN . +Several parameters are affected, like the number of layers, +the transmission rate of the base layer (which also defines the +transmission rate of all the upper layers), and the symbol size +(with Internet communications 512 byte symbols are used to avoid +any risk of fragmentation, on a LAN higher values are possible). + +Argument: int + +.TP +.I MCL_OPT_DATAGRAM_SIZE: +Datagram (i.e. symbol) size. +Be carefull if a value superior to 512 bytes is used as IP datagram +fragmentation (which is considered non efficient) may take place. + +Argument: int + +.TP +.I MCL_OPT_TX_RATE: +Transmission rate in symbols per second on the base layer +(it must be an integral number). +The transmission rate on all the upper layers are affected +as they are multiples. + +Argument: int + +.TP +.I MCL_OPT_SET_FEC_CODE: +Specifies the FEC code to use from now on. +Possible choices are currently: +.I MCL_FEC_CODE_NULL, MCL_FEC_CODE_RSE, MCL_FEC_CODE_LDGM +and +.I MCL_FEC_CODE_LDPC. +It is important that setting the FEC code takes place before selecting +the FEC ratio, since this latter operates on the current FEC code, not all +possible FEC codes. +Only the sender needs to specify the FEC code to be used, the +receiver will automatically switch to the appropriate decoder, +taking into account the FEC information of the ALC/LCT header. +Several FEC codes can be used simultaneously in the same ALC session, +with an object granularity (i.e. all blocks of an object use the +same FEC code). + +Argument: int (one of the above MCL_FEC_CODE_XXX values) + +.TP +.I MCL_OPT_FEC_RATIO: +Specifies the FEC ratio (a floating point number) to use. +This ratio is given by total_nb_of_symbols / nb_of_data_symbols (or n / k), +so a fec_ratio of 1.0 means no FEC at all, a fec_ratio of 2.0 means +"as many FEC symbols as there are data symbols", etc. +This ratio is the inverse of the ``code rate'' (following the official +coding theory terminology). + +Argument: float + +.TP +.I MCL_OPT_REUSE_APPLI_TX_BUFFER: + +Argument: int + +.TP +.I MCL_OPT_VIRTUAL_TX_MEMORY: +Controls the virtual transmission memory service where data +(and FEC) is stored on disk rather than in physical memory. +The localization of the file can be controlled with the +.I MCL_OPT_TMP_DIR +option. + +Argument: int (0 or 1) + +.TP +.I MCL_OPT_KEEP_DATA: +Used in case of multiple objects to do symbol scheduling in +a whole rather than independantly for each object. +Works with the +.I MCL_OPT_PUSH_DATA +option. +This option must be specified +.I before +the first object submission. + +Argument: none + +.TP +.I MCL_OPT_PUSH_DATA: +Used in case of multiple objects to do symbol scheduling in +a whole rather than independantly for each object. +Works with the +.I MCL_OPT_KEEP_DATA +option. +This option must be specified +.I after +the submission of the last object. + +Argument: none + +.TP +.I MCL_OPT_SCHED: +Specifies the symbol scheduler (i.e. what symbols to send on what layer) +to use. +Currently one can choose either +.I MCL_SCHED_LCT1 +(send the same symbols on each layer) or +.I MCL_SCHED_LCT2 +(send data on the base layer, a first set of FEC symbols on layer 1, +a second set of FEC symbols on layer 2, etc.), or +.I MCL_SCHED_LCT3 +(similar to version 2 but dedicated to huge objects). + +Argument: int + +.TP +.I MCL_OPT_OBJ_SCHED +Specifies the object scheduler (i.e. with multiple objects +in what order should the objects be scheduled on the various layers). +Currently one can choose +.I MCL_SCHED_SEQUENTIAL_OBJ_ORDER , +.I MCL_SCHED_RANDOM_OBJ_ORDER , +.I MCL_SCHED_PARTIALLY_MIXED_ORDER , or +.I MCL_SCHED_MIXED_ORDER. + +Argument: int +.PP + +Receiver specific options: + +.TP +.I MCL_OPT_IMMEDIATE_DELIVERY: +In case of multi-object session, do you want that an object be delivered +to the application as soon as it has been completely received or not? +If enabled, then objects may be delivered out of order... + +Argument: int (0 or 1) + +.TP +.I MCL_OPT_POSTPONE_FEC_DECODING: +Do not decode FEC symbols immediately but wait until enough +symbols have been received for each block to start decoding. +Highly recommended with slow FEC codecs (like the Reed-Solomon +codec) and high speed reception rates. + +Argument: int + +.TP +.I MCL_OPT_SEQNB_STATS: +(deprecated) + +Argument: int + +.TP +.I MCL_OPT_NEVER_LEAVE_BASE_LAYER: +The library will not try to leave the base layer after +the successfull decoding of all objects. This is required by the +.I MCL_WAIT_EVENT_CLOSED +event (see mcl_wait_event(2) manual). +Note that even without this option, even in front of losses, +a receiver is guaranted not to leave the base layer during +symbol transfer. + +Argument: int (0 (default) or 1) + +.PP + +See the file "src/mcl_lib.h" and the MCL documentation for additional +information. + + +.SH RETURN VALUE + +On success returns 0, on error a non-zero value. + + +.SH EXAMPLE + +Here is a simple example. + +.nf + int port = 2324; /* in host format! */ + int err = 0; + + if (err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port))) { + printf("error, mcl_ctl failed\\n"); + exit(1); + } +.fi + + +.SH BUGS / LIMITATIONS + +The session cannot be fully initialized (in particular the subscription +to all multicast groups) before we are sure that all control parameters have +been negociated with the various +.I mcl_ctl() +calls. +By convention, the MCL library assumes that once an +.I mcl_send(to) +or +.I mcl_recv(from) +call is issued, all the principal control parameters have been +issued and the session initialization can be finished. +It means that packets destinated to the target multicast groups +before a receiver has issued the first +.I mcl_recv(from) +will all be lost, even if the multicast group/port number have +been specified. +To avoid it, +.I mcl_recv(from) +can be called with a null buffer and/or a nul buffer len +just after the specification of the target multicast group +and port number (and demux label if any). + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2003 INRIA - Universite Paris 6 - +All rights reserved +(main author: Vincent Roca - vincent.roca@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR mcl_open (3), +.BR MCL +documentation + + +.SH AUTHORS + +Vincent Roca (INRIA Rhone-Alpes, Planete project) + +$Id: mcl_ctl.man.3,v 1.2 2003/11/28 10:05:31 roca Exp $ diff --git a/man/mcl_ctl.man.3.html b/man/mcl_ctl.man.3.html new file mode 100644 index 0000000..81ddc11 --- /dev/null +++ b/man/mcl_ctl.man.3.html @@ -0,0 +1,554 @@ +Content-type: text/html + +Manpage of MCL_CTL + +

MCL_CTL

+Section: Misc. Reference Manual Pages (3)
Updated:
Index +Return to Main Contents
+ +

+  +

NAME

+ +

+mcl_ctl - control function of the MultiCast Library (MCL) +

+

+  +

SYNOPSIS

+ +

+

+ #include "../src/common/mcl_lib_api.h" +

+ int mcl_ctl (int id, int optname, void* optvalue, int optlen); +

+ +

+  +

DESCRIPTION

+ +

+mcl_ctl + +is meant to control all the internal options of the MCL library +and to offer the possibility to override default values. +Most of these options only apply to the current session (identified +by the +id + +identifier). +

+The arguments are: +

+

+
int id + +
+session identifier returned by +mcl_open + +
int optname + +
+option name +
void* optvalue + +
+pointer to the value area. Depending on the option, this value can +be provided to MCL (to set an option), or be modified and returned by MCL +(to read the current value of an option). +
int optlen + +
+length of the value area. +
+

+ +

+The following options are defined: +

+

+
MCL_OPT_LAYER_NB: + +
+maximum number of layers used by a traffic source or a receiver (it depends +on the congestion flow control module). +

+Argument: int +

+

MCL_OPT_SINGLE_LAYER: + +
+This argument optimizes transmissions for the single layer, fixed rate, +no congestion-control case. +

+Argument: int (0 or 1) +

+

+

MCL_OPT_PORT: + +
+UDP port number in host order. +Another way to specify the port number is to use MCL_OPT_BIND option. +

+Argument: int (and not a short!) +

+

MCL_OPT_ADDR: + +
+Another way to specify the address is to use MCL_OPT_BIND option. +IPv4 address in host order. +

+Argument: int +

+

MCL_OPT_BIND: + +
+This is an alternative to the +MCL_OPT_PORT + +and +MCL_OPT_ADDR + +options. +It's use is exactly the same as that of the Socket +bind() + +system call. +The struct sockaddr supplied is in network order (use hton functions first). +

+Argument: struct sockaddr +

+

MCL_OPT_DEMUX_LABEL: + +
+Specify the demultiplexing label to use on that session, also called +Transport Session Identifier (TSI) in the ALC/LCT drafts. +

+Argument: int +

+

MCL_OPT_TTL: + +
+IP Time To Live (TTL) value. This parameters controls the scope of unicast +and multicast packets generated by the traffic source. +Use with care as large values of TTL can easily lead to flooding the whole +MBONE. +

+Argument: int +

+

MCL_OPT_STATS: + +
+Controls the print of statistics during transmissions. +A value of 0 will avoid any print (but statistics are anyway gathered), +1 will lead to print major statistics (e.g. at the end of reception), +and 2 will lead to print statistics regularly. +

+Argument: int +

+

MCL_OPT_VERBOSITY: + +
+This option is only usefull if the MCL library has been compiled with the +DEBUG flag. +It controls the level of verbosity desired. +It can range from 0 (quiet mode, the default), to 6 (full verbosity, +with a message each time an MCL internal function is called). +Usefull for debug and to know what's going on... +A value of 2 is required to collect major events and do post analysis +of a session using the tools in the "test" directory. +

+Argument: int +

+

MCL_OPT_MOREABOUT: + +
+Get release information, compilation flags and credits. +

+Argument: none +

+

MCL_OPT_TMP_DIR: + +
+Specify the directory to use for temporary files +(e.g. for the virtual transmission memory service). +

+Argument: null terminated string (give the strlen() of this string in +the optlen argument) +

+

MCL_OPT_NETIF: + +
+Network interface, in host order, to use. +Only usefull in case of multi-homed hosts or routers. +

+Argument: int +

+

MCL_OPT_LOOPBACK: + +
+Should receivers on the same host as the source also receive data? +(by default yes). +Rarely usefull! +

+Argument: int +

+

+

+ +Source specific options: +

+

+

+
MCL_OPT_DELIVERY_MODE: + +
+Used by the traffic source (only) to specify the delivery mode. +Currently, this mode can be +DEL_MODE_PUSH + +for transmissions in ``push'' mode (i.e. data is sent once, all +the receivers must be ready) and +DEL_MODE_ON_DEMAND + +for transmissions in ``on-demand'' mode (i.e. data is sent continuously +in cycles, receivers can arrive at any time, get data and leave). +

+Argument: int ( +DEL_MODE_PUSH + +or +DEL_MODE_ON_DEMAND + +) +

+

MCL_OPT_TX_PROFILE: + +
+Select a predefined transmission profile. +Currently this profile can be one of +MCL_TX_PROFILE_LOW_RATE_INTERNET + +, +MCL_TX_PROFILE_MID_RATE_INTERNET + +, or +MCL_TX_PROFILE_HIGH_SPEED_LAN . + +Several parameters are affected, like the number of layers, +the transmission rate of the base layer (which also defines the +transmission rate of all the upper layers), and the symbol size +(with Internet communications 512 byte symbols are used to avoid +any risk of fragmentation, on a LAN higher values are possible). +

+Argument: int +

+

MCL_OPT_DATAGRAM_SIZE: + +
+Datagram (i.e. symbol) size. +Be carefull if a value superior to 512 bytes is used as IP datagram +fragmentation (which is considered non efficient) may take place. +

+Argument: int +

+

MCL_OPT_TX_RATE: + +
+Transmission rate in symbols per second on the base layer +(it must be an integral number). +The transmission rate on all the upper layers are affected +as they are multiples. +

+Argument: int +

+

MCL_OPT_SET_FEC_CODE: + +
+Specifies the FEC code to use from now on. +Possible choices are currently: +MCL_FEC_CODE_NULL, MCL_FEC_CODE_RSE, MCL_FEC_CODE_LDGM + +and +MCL_FEC_CODE_LDPC. + +It is important that setting the FEC code takes place before selecting +the FEC ratio, since this latter operates on the current FEC code, not all +possible FEC codes. +Only the sender needs to specify the FEC code to be used, the +receiver will automatically switch to the appropriate decoder, +taking into account the FEC information of the ALC/LCT header. +Several FEC codes can be used simultaneously in the same ALC session, +with an object granularity (i.e. all blocks of an object use the +same FEC code). +

+Argument: int (one of the above MCL_FEC_CODE_XXX values) +

+

MCL_OPT_FEC_RATIO: + +
+Specifies the FEC ratio (a floating point number) to use. +This ratio is given by total_nb_of_symbols / nb_of_data_symbols (or n / k), +so a fec_ratio of 1.0 means no FEC at all, a fec_ratio of 2.0 means +"as many FEC symbols as there are data symbols", etc. +This ratio is the inverse of the ``code rate'' (following the official +coding theory terminology). +

+Argument: float +

+

MCL_OPT_REUSE_APPLI_TX_BUFFER: + +
+

+Argument: int +

+

MCL_OPT_VIRTUAL_TX_MEMORY: + +
+Controls the virtual transmission memory service where data +(and FEC) is stored on disk rather than in physical memory. +The localization of the file can be controlled with the +MCL_OPT_TMP_DIR + +option. +

+Argument: int (0 or 1) +

+

MCL_OPT_KEEP_DATA: + +
+Used in case of multiple objects to do symbol scheduling in +a whole rather than independantly for each object. +Works with the +MCL_OPT_PUSH_DATA + +option. +This option must be specified +before + +the first object submission. +

+Argument: none +

+

MCL_OPT_PUSH_DATA: + +
+Used in case of multiple objects to do symbol scheduling in +a whole rather than independantly for each object. +Works with the +MCL_OPT_KEEP_DATA + +option. +This option must be specified +after + +the submission of the last object. +

+Argument: none +

+

MCL_OPT_SCHED: + +
+Specifies the symbol scheduler (i.e. what symbols to send on what layer) +to use. +Currently one can choose either +MCL_SCHED_LCT1 + +(send the same symbols on each layer) or +MCL_SCHED_LCT2 + +(send data on the base layer, a first set of FEC symbols on layer 1, +a second set of FEC symbols on layer 2, etc.), or +MCL_SCHED_LCT3 + +(similar to version 2 but dedicated to huge objects). +

+Argument: int +

+

MCL_OPT_OBJ_SCHED + +
+Specifies the object scheduler (i.e. with multiple objects +in what order should the objects be scheduled on the various layers). +Currently one can choose +MCL_SCHED_SEQUENTIAL_OBJ_ORDER , + +MCL_SCHED_RANDOM_OBJ_ORDER , + +MCL_SCHED_PARTIALLY_MIXED_ORDER , or + +MCL_SCHED_MIXED_ORDER. + +

+Argument: int +

+

+ +

+Receiver specific options: +

+

+
MCL_OPT_IMMEDIATE_DELIVERY: + +
+In case of multi-object session, do you want that an object be delivered +to the application as soon as it has been completely received or not? +If enabled, then objects may be delivered out of order... +

+Argument: int (0 or 1) +

+

MCL_OPT_POSTPONE_FEC_DECODING: + +
+Do not decode FEC symbols immediately but wait until enough +symbols have been received for each block to start decoding. +Highly recommended with slow FEC codecs (like the Reed-Solomon +codec) and high speed reception rates. +

+Argument: int +

+

MCL_OPT_SEQNB_STATS: + +
+(deprecated) +

+Argument: int +

+

MCL_OPT_NEVER_LEAVE_BASE_LAYER: + +
+The library will not try to leave the base layer after +the successfull decoding of all objects. This is required by the +MCL_WAIT_EVENT_CLOSED + +event (see mcl_wait_event(2) manual). +Note that even without this option, even in front of losses, +a receiver is guaranted not to leave the base layer during +symbol transfer. +

+Argument: int (0 (default) or 1) +

+

+

+ +

+See the file "src/mcl_lib.h" and the MCL documentation for additional +information. +

+

+  +

RETURN VALUE

+ +

+On success returns 0, on error a non-zero value. +

+

+  +

EXAMPLE

+ +

+Here is a simple example. +

+

+        int     port = 2324;    /* in host format! */
+        int     err = 0;
+
+        if (err = mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port))) {
+                printf("error, mcl_ctl failed\n");
+                exit(1);
+        }
+
+ +

+

+  +

BUGS / LIMITATIONS

+ +

+The session cannot be fully initialized (in particular the subscription +to all multicast groups) before we are sure that all control parameters have +been negociated with the various +mcl_ctl() + +calls. +By convention, the MCL library assumes that once an +mcl_send(to) + +or +mcl_recv(from) + +call is issued, all the principal control parameters have been +issued and the session initialization can be finished. +It means that packets destinated to the target multicast groups +before a receiver has issued the first +mcl_recv(from) + +will all be lost, even if the multicast group/port number have +been specified. +To avoid it, +mcl_recv(from) + +can be called with a null buffer and/or a nul buffer len +just after the specification of the target multicast group +and port number (and demux label if any). +

+

+  +

COPYRIGHTS

+ +

+

+Copyright (c) 1999-2003 INRIA - Universite Paris 6 -
+All rights reserved
+(main author: Vincent Roca - vincent.roca@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ +

+

+  +

SEE ALSO

+ +

+mcl_open(3), + +MCL + +documentation +

+

+  +

AUTHORS

+ +

+Vincent Roca (INRIA Rhone-Alpes, Planete project) +

+$Id: mcl_ctl.man.3,v 1.2 2003/11/28 10:05:31 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
RETURN VALUE
+
EXAMPLE
+
BUGS / LIMITATIONS
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/mcl_open.man.3 b/man/mcl_open.man.3 new file mode 100644 index 0000000..6272ffb --- /dev/null +++ b/man/mcl_open.man.3 @@ -0,0 +1,102 @@ +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH MCL_OPEN "3" "" "MCLv3 Reference Manual" + + +.SH NAME + +mcl_open \- open an MCL (MultiCast Library) session + + +.SH SYNOPSIS + +.sp +\fB #include "../src/common/mcl_lib_api.h"\fI + +\fB int mcl_open (const char* \fImode\fB);\fI +.fi + +.SH DESCRIPTION + +Mode can be +.I "w" +to open an MCL sending session (i.e. to be a source), +.I "r" +to open an MCL receiving session (i.e. to receive data). +Two other mode, +.I "wr" +and +.I "rw" +exist in cases where you want to do both. The order is important. +In +.I "wr" +mode, the session is essentially a sending session, while in +.I "rw" +mode the session is essentially a receiving session. +Their use is still a bit experimental. + + +.SH RETURN VALUE + +On success returns an MCL identifier, that will be used thenafter +in all mcl functions, on error a negative (< 0) value. +Note that the MCL identifier is unique in the system file descriptor +space to avoid any possible confusion. + + +.SH EXAMPLE + +Here is a simple example to open an MCL session as a source. + +.nf + int id; + + if ((id = mcl_open("w")) < 0) { + printf("ERROR: mcl_open failed\n"); + exit(-1); + } +.fi + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2003 INRIA - Universite Paris 6 - +All rights reserved +(main author: Vincent Roca - vincent.roca@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR MCL +documentation + + +.SH AUTHORS + +Vincent Roca (INRIA Rhone-Alpes, Planete project) + +$Id: mcl_open.man.3,v 1.2 2003/11/28 10:05:31 roca Exp $ diff --git a/man/mcl_open.man.3.html b/man/mcl_open.man.3.html new file mode 100644 index 0000000..b9ef03b --- /dev/null +++ b/man/mcl_open.man.3.html @@ -0,0 +1,136 @@ +Content-type: text/html + +Manpage of MCL_OPEN + +

MCL_OPEN

+Section: Misc. Reference Manual Pages (3)
Updated:
Index +Return to Main Contents
+ +

+

+  +

NAME

+ +

+mcl_open - open an MCL (MultiCast Library) session +

+

+  +

SYNOPSIS

+ +

+

+ #include "../src/common/mcl_lib_api.h" +

+ int mcl_open (const char* mode); + +

+  +

DESCRIPTION

+ +

+Mode can be +w + +to open an MCL sending session (i.e. to be a source), +r + +to open an MCL receiving session (i.e. to receive data). +Two other mode, +wr + +and +rw + +exist in cases where you want to do both. The order is important. +In +wr + +mode, the session is essentially a sending session, while in +rw + +mode the session is essentially a receiving session. +Their use is still a bit experimental. +

+

+  +

RETURN VALUE

+ +

+On success returns an MCL identifier, that will be used thenafter +in all mcl functions, on error a negative (< 0) value. +Note that the MCL identifier is unique in the system file descriptor +space to avoid any possible confusion. +

+

+  +

EXAMPLE

+ +

+Here is a simple example to open an MCL session as a source. +

+

+        int     id;
+
+        if ((id = mcl_open("w")) < 0) {
+                printf("ERROR: mcl_open failed);
+                exit(-1);
+        }
+
+ +

+

+  +

COPYRIGHTS

+ +

+

+Copyright (c) 1999-2003 INRIA - Universite Paris 6 -
+All rights reserved
+(main author: Vincent Roca - vincent.roca@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ +

+

+  +

SEE ALSO

+ +

+MCL + +documentation +

+

+  +

AUTHORS

+ +

+Vincent Roca (INRIA Rhone-Alpes, Planete project) +

+$Id: mcl_open.man.3,v 1.2 2003/11/28 10:05:31 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
RETURN VALUE
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/mcl_recv.man.3 b/man/mcl_recv.man.3 new file mode 100644 index 0000000..3dd6d4b --- /dev/null +++ b/man/mcl_recv.man.3 @@ -0,0 +1,193 @@ +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH MCL_RECV "3" "" "MCLv3 Reference Manual" + + +.SH NAME + +mcl_recv - mcl_recvfrom - mcl_recvmsg - receive data from an MCL (MultiCast Library) session + + +.SH SYNOPSIS + +.sp +\fB #include "../src/common/mcl_lib_api.h"\fI + +\fB int mcl_recv (int \fIid\fB, char *\fIbuf\fB, int \fIbuflen\fB);\fI + +\fB int mcl_recvfrom (int \fIid\fB, char *\fIbuf\fB, int \fIbuflen\fB, struct sockaddr *\fIsaddr\fB, int *\fIsaddr_len\fB);\fI + +\fB int mcl_recvmsg (int \fIid\fB, struct mcl_msghdr *\fImsg\fB, mcl_msgflag \fIflags\fB);\fI +.fi + + +.SH DESCRIPTION + +Receives data from an MCL session, retrieving the source address in +case of the +.I mcl_recvfrom() +call. +These three calls are blocking (synchronous), until data is available +or an event occurs. + +The +.I mcl_recvmsg() +call enables scattering and offers many possibilities not offered by +the other two functions. +For instance a peek flag is available to avoid that data copied to +the application buffer be removed from the reception object list. +Further calls to +.I mcl_recv* +functions will therefore return the same data. +Another flag enables the receiving application to know the amount of +data available without reading anything. A further call to +.I mcl_recv* +functions will return the same object (whose length is now known). +Usefull to allocate a buffer of the right size. +The following struture is used for scatter: + +.nf +/** + * Flags that can be used by the mcl_sndmsg/mcl_recvmsg + * functions. + */ +enum mcl_msgflag { + MCL_MSG_DEFAULT = 0,/* This flag is the default behavior */ + /* copyh data and remove it from the */ + /* received and decoded object list */ + MCL_MSG_PEEK, /* This flag causes the receive operation */ + /* to return data from the beginning of the */ + /* receive queue without removing that data */ + /* from the queue. Thus, a subsequent */ + /* receive call will return the same data. */ + MCL_MSG_CHECK_IF_DATA_IS_AVAILABLE + /* This flag causes the receive application */ + /* to return the amount of data available for */ + /* a future read. Usefull to have an idea of */ + /* the buffer size required for a future */ + /* read. */ +}; + + +/** + * Structure for scatter/gather I/O, and used by the + * mcl_sndmsg/mcl_recvmsg functions. + */ +struct mcl_iovec { + int iov_type; /* type of storage (file or buffer) */ + void *iov_base; /* pointer to buffer storage area */ + int iov_fd; /* file descriptor to be used as */ + /* storage area */ + int iov_offset; /* offset from iov_base (only significant */ + /* in case of file storage type) */ + int iov_len; /* length of data */ +}; + +#define MCL_IOV_TYPE_BUFFER 0 +#define MCL_IOV_TYPE_FILE 1 + +/** + * Message control structure used by mcl_sndmsg/mcl_recvmsg + * functions. + */ +struct mcl_msghdr { + void *msg_name; /* optional address */ + int msg_namelen; /* size of address */ + struct mcl_iovec *msg_iov; /* scatter/gather array */ + int msg_iovlen; /* # elements in msg_iov */ + //void *msg_control; /* ancillary data, see below */ + //int msg_controllen; /* ancillary data buffer len */ + //int msg_flags; /* flags on received message */ +}; +.fi + + +Calling +.I mcl_recv() +or +.I mcl_recvfrom() +with an identifier that does not refer to an MCL session leads to calling the +.I recv() +or +.I recvfrom() +system call with the same parameters. + + +.SH RETURN VALUE + +Returns the number of bytes received, or a negative (< 0) value in case of +error. +Note that issuing an +.I mcl_recv() +or +.I mcl_recvfrom() +on a session that is closed by the source, or where all objects +have been received and returned to the application, triggers an +error. This is the usual way of detecting the "end of session" +(see example below). + + +.SH EXAMPLE + +Here is a simple example (receiving side): + +.nf + int id; + int len; + char buf[BUFLEN]; + + while ((len = mcl_recv(id, buf, BUFLEN)) > 0) { + + } + /* session closed by source */ + mcl_close(id); +.fi + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2003 INRIA - Universite Paris 6 - +All rights reserved +(main author: Vincent Roca - vincent.roca@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.I MCL +documentation, +.I recv() +or +.I recvfrom() +man pages + + + +.SH AUTHORS + +Vincent Roca (INRIA Rhone-Alpes, Planete project) + +$Id: mcl_recv.man.3,v 1.3 2004/08/06 07:16:26 roca Exp $ diff --git a/man/mcl_recv.man.3.html b/man/mcl_recv.man.3.html new file mode 100644 index 0000000..3a58600 --- /dev/null +++ b/man/mcl_recv.man.3.html @@ -0,0 +1,234 @@ +Content-type: text/html + +Manpage of MCL_RECV + +

MCL_RECV

+Section: Misc. Reference Manual Pages (3)
Updated:
Index +Return to Main Contents
+ +

+

+  +

NAME

+ +

+mcl_recv - mcl_recvfrom - mcl_recvmsg - receive data from an MCL (MultiCast Library) session +

+

+  +

SYNOPSIS

+ +

+

+ #include "../src/common/mcl_lib_api.h" +

+ int mcl_recv (int id, char *buf, int buflen); +

+ int mcl_recvfrom (int id, char *buf, int buflen, struct sockaddr *saddr, int *saddr_len); +

+ int mcl_recvmsg (int id, struct mcl_msghdr *msg, mcl_msgflag flags); + +

+

+  +

DESCRIPTION

+ +

+Receives data from an MCL session, retrieving the source address in +case of the +mcl_recvfrom() + +call. +These three calls are blocking (synchronous), until data is available +or an event occurs. +

+The +mcl_recvmsg() + +call enables scattering and offers many possibilities not offered by +the other two functions. +For instance a peek flag is available to avoid that data copied to +the application buffer be removed from the reception object list. +Further calls to +mcl_recv* + +functions will therefore return the same data. +Another flag enables the receiving application to know the amount of +data available without reading anything. A further call to +mcl_recv* + +functions will return the same object (whose length is now known). +Usefull to allocate a buffer of the right size. +The following struture is used for scatter: +

+

+/**
+ * Flags that can be used by the mcl_sndmsg/mcl_recvmsg
+ * functions.
+ */
+enum mcl_msgflag {
+        MCL_MSG_DEFAULT = 0,/* This flag is the default behavior */
+                        /* copyh data and remove it from the */
+                        /* received and decoded object list */
+        MCL_MSG_PEEK,   /* This flag causes the receive operation */
+                        /* to return data from the beginning of the */
+                        /* receive queue without removing that data */
+                        /* from the queue. Thus, a subsequent */
+                        /* receive call will return the same data. */
+        MCL_MSG_CHECK_IF_DATA_IS_AVAILABLE
+                        /* This flag causes the receive application */
+                        /* to return the amount of data available for */
+                        /* a future read. Usefull to have an idea of */
+                        /* the buffer size required for a future */
+                        /* read. */
+};
+
+
+/**
+ * Structure for scatter/gather I/O, and used by the
+ * mcl_sndmsg/mcl_recvmsg functions.
+ */
+struct mcl_iovec {
+        int   iov_type;    /* type of storage (file or buffer) */
+        void  *iov_base;   /* pointer to buffer storage area */ 
+        int   iov_fd;      /* file descriptor to be used as */
+                           /* storage area */
+        int   iov_offset;  /* offset from iov_base (only significant */
+                           /* in case of file storage type) */
+        int   iov_len;     /* length of data */
+};
+
+#define MCL_IOV_TYPE_BUFFER     0
+#define MCL_IOV_TYPE_FILE       1
+
+/**
+ * Message control structure used by mcl_sndmsg/mcl_recvmsg
+ * functions.
+ */
+struct mcl_msghdr {
+        void            *msg_name;      /* optional address */
+        int             msg_namelen;    /* size of address */
+        struct mcl_iovec *msg_iov;      /* scatter/gather array */
+        int             msg_iovlen;     /* # elements in msg_iov */
+        //void          *msg_control;   /* ancillary data, see below */
+        //int           msg_controllen; /* ancillary data buffer len */
+        //int           msg_flags;      /* flags on received message */
+};
+
+ +

+

+Calling +mcl_recv() + +or +mcl_recvfrom() + +with an identifier that does not refer to an MCL session leads to calling the +recv() + +or +recvfrom() + +system call with the same parameters. +

+

+  +

RETURN VALUE

+ +

+Returns the number of bytes received, or a negative (< 0) value in case of +error. +Note that issuing an +mcl_recv() + +or +mcl_recvfrom() + +on a session that is closed by the source, or where all objects +have been received and returned to the application, triggers an +error. This is the usual way of detecting the "end of session" +(see example below). +

+

+  +

EXAMPLE

+ +

+Here is a simple example (receiving side): +

+

+        int     id;
+        int     len;
+        char    buf[BUFLEN];
+
+        while ((len = mcl_recv(id, buf, BUFLEN)) > 0) {
+                <do what needs to be done with data...>
+        }
+        /* session closed by source */
+        mcl_close(id);
+
+ +

+

+  +

COPYRIGHTS

+ +

+

+Copyright (c) 1999-2003 INRIA - Universite Paris 6 -
+All rights reserved
+(main author: Vincent Roca - vincent.roca@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ +

+

+  +

SEE ALSO

+ +

+MCL + +documentation, +recv() + +or +recvfrom() + +man pages +

+

+

+  +

AUTHORS

+ +

+Vincent Roca (INRIA Rhone-Alpes, Planete project) +

+$Id: mcl_recv.man.3,v 1.3 2004/08/06 07:16:26 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
RETURN VALUE
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/mcl_send.man.3 b/man/mcl_send.man.3 new file mode 100644 index 0000000..ba85216 --- /dev/null +++ b/man/mcl_send.man.3 @@ -0,0 +1,115 @@ +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH MCL_SEND "3" "" "MCLv3 Reference Manual" + + +.SH NAME + +mcl_send - mcl_sendto - send data to an MCL (MultiCast Library) session + + +.SH SYNOPSIS + +.sp +\fB #include "../src/common/mcl_lib_api.h"\fI + +\fB int mcl_send (int \fIid\fB, const void *\fIbuf\fB, int \fIbuflen\fB);\fI + +\fB int mcl_sendto (int \fIid\fB, const void *\fIbuf\fB, int \fIbuflen\fB, const struct sockaddr *\fIsaddr\fB, int \fIsaddr_len\fB);\fI +.fi + + +.SH DESCRIPTION + +Sends data on an MCL session, specifying the destination address in +case of the +.I mcl_sendto +call. +These two calls are non blocking (asynchronous). + +Calling +.I mcl_send() +or +.I mcl_sendto() +with an identifier that does not refer to an +MCL session leads to calling the +.I send() +or +.I sendto() +system call. + + +.SH RETURN VALUE + +Returns the number of bytes sent on success, or a negative (< 0) value in +case of error. + +Note that issuing an +.I mcl_send() +or +.I mcl_sendto() +on a session that is closed by the source triggers an error. + + +.SH EXAMPLE + +Here is a simple example (sending side): + +.nf + int id; + int len; + char buf[BUFLEN]; + + if (mcl_send(id, buf, BUFLEN) < 0) + printf("ERROR: mcl_send failed"); + exit(-1); + } +.fi + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2003 INRIA - Universite Paris 6 - +All rights reserved +(main author: Vincent Roca - vincent.roca@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.I MCL +documentation, +.I send() +or +.I sendto() +man pages + + +.SH AUTHORS + +Vincent Roca (INRIA Rhone-Alpes, Planete project) + +$Id: mcl_send.man.3,v 1.2 2003/11/28 10:05:31 roca Exp $ diff --git a/man/mcl_send.man.3.html b/man/mcl_send.man.3.html new file mode 100644 index 0000000..df2d7b1 --- /dev/null +++ b/man/mcl_send.man.3.html @@ -0,0 +1,152 @@ +Content-type: text/html + +Manpage of MCL_SEND + +

MCL_SEND

+Section: Misc. Reference Manual Pages (3)
Updated:
Index +Return to Main Contents
+ +

+

+  +

NAME

+ +

+mcl_send - mcl_sendto - send data to an MCL (MultiCast Library) session +

+

+  +

SYNOPSIS

+ +

+

+ #include "../src/common/mcl_lib_api.h" +

+ int mcl_send (int id, const void *buf, int buflen); +

+ int mcl_sendto (int id, const void *buf, int buflen, const struct sockaddr *saddr, int saddr_len); + +

+

+  +

DESCRIPTION

+ +

+Sends data on an MCL session, specifying the destination address in +case of the +mcl_sendto + +call. +These two calls are non blocking (asynchronous). +

+Calling +mcl_send() + +or +mcl_sendto() + +with an identifier that does not refer to an +MCL session leads to calling the +send() + +or +sendto() + +system call. +

+

+  +

RETURN VALUE

+ +

+Returns the number of bytes sent on success, or a negative (< 0) value in +case of error. +

+Note that issuing an +mcl_send() + +or +mcl_sendto() + +on a session that is closed by the source triggers an error. +

+

+  +

EXAMPLE

+ +

+Here is a simple example (sending side): +

+

+        int     id;
+        int     len;
+        char    buf[BUFLEN];
+
+        if (mcl_send(id, buf, BUFLEN) < 0)
+                printf("ERROR: mcl_send failed");
+                exit(-1);
+        }
+
+ +

+

+  +

COPYRIGHTS

+ +

+

+Copyright (c) 1999-2003 INRIA - Universite Paris 6 -
+All rights reserved
+(main author: Vincent Roca - vincent.roca@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ +

+

+  +

SEE ALSO

+ +

+MCL + +documentation, +send() + +or +sendto() + +man pages +

+

+  +

AUTHORS

+ +

+Vincent Roca (INRIA Rhone-Alpes, Planete project) +

+$Id: mcl_send.man.3,v 1.2 2003/11/28 10:05:31 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
RETURN VALUE
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/mcl_wait_event.man.3 b/man/mcl_wait_event.man.3 new file mode 100644 index 0000000..3f16f39 --- /dev/null +++ b/man/mcl_wait_event.man.3 @@ -0,0 +1,137 @@ +.\" +.\" Copyright (c) 1999-2003 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH MCL_WAIT_EVENT "3" "" "MCLv3 Reference Manual" + + +.SH NAME + +mcl_wait_event \- wait an event of the MultiCast Library (MCL) + + +.SH SYNOPSIS + +.sp +\fB #include "../src/common/mcl_lib_api.h"\fI + +\fB int mcl_wait_event (int \fIid\fB, int \fIevent\fB);\fI +.fi + +.SH DESCRIPTION + +.B mcl_wait_event +enables the application to sleep until the event specified occurs. +It applies to the current session (identified +by the +.B id +identifier). +As this function uses polling, it may not be awaken immediately +after that the expected event has occurred. + +The arguments are: + +.TP +.B int id +session identifier returned by +.B mcl_open + +.TP +.B int event +event name. +.PP + +The following events are defined: +.TP +.I MCL_WAIT_EVENT_END_TX: +wait the end of transmission of the last symbol of each layer +(which can take quite a long time on the slowest layer). +Only valid with a traffic source. + +.TP +.I MCL_WAIT_EVENT_END_RX: +wait the end of reception (i.e. once enough symbols have been +received to decode all objects) or until the MCL session +has received a ``CLOSE'' message from the traffic source. +Only valid at a receiver. + +.TP +.I MCL_WAIT_EVENT_CLOSED: +wait untill a +.I CLOSE +message has been received, meaning that no symbol will ever been +sent for this session. + +Using +.I MCL_WAIT_EVENT_CLOSED +requires that a +.I MCL_OPT_NEVER_LEAVE_BASE_LAYER +(see mcl_ctl(3) manual) has been issued at the session start. +Indeed, +.I CLOSE +messages are sent on the base layer and without this option +the receiver leaves the base layer once all objects have been +successfully decoded. + + +.SH RETURN VALUE + +On success returns 0, on error a non-zero value. + + +.SH EXAMPLE + +Here is a simple example. + +.nf + int err = 0; + + if ((err = mcl_wait_event(id, MCL_WAIT_EVENT_END_TX)) < 0) { + printf("ERROR: mcl_wait_event failed\n"); + exit(-1); + } +.fi + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2003 INRIA - Universite Paris 6 - +All rights reserved +(main author: Vincent Roca - vincent.roca@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR mcl_open(), +.BR MCL +documentation + + +.SH AUTHORS + +Vincent Roca (INRIA Rhone-Alpes, Planete project) + +$Id: mcl_wait_event.man.3,v 1.2 2003/11/28 10:05:31 roca Exp $ diff --git a/man/mcl_wait_event.man.3.html b/man/mcl_wait_event.man.3.html new file mode 100644 index 0000000..8d85015 --- /dev/null +++ b/man/mcl_wait_event.man.3.html @@ -0,0 +1,182 @@ +Content-type: text/html + +Manpage of MCL_WAIT_EVENT + +

MCL_WAIT_EVENT

+Section: Misc. Reference Manual Pages (3)
Updated:
Index +Return to Main Contents
+ +

+

+  +

NAME

+ +

+mcl_wait_event - wait an event of the MultiCast Library (MCL) +

+

+  +

SYNOPSIS

+ +

+

+ #include "../src/common/mcl_lib_api.h" +

+ int mcl_wait_event (int id, int event); + +

+  +

DESCRIPTION

+ +

+mcl_wait_event + +enables the application to sleep until the event specified occurs. +It applies to the current session (identified +by the +id + +identifier). +As this function uses polling, it may not be awaken immediately +after that the expected event has occurred. +

+The arguments are: +

+

+
int id + +
+session identifier returned by +mcl_open + +

+

int event + +
+event name. +
+

+ +

+The following events are defined: +

+
MCL_WAIT_EVENT_END_TX: + +
+wait the end of transmission of the last symbol of each layer +(which can take quite a long time on the slowest layer). +Only valid with a traffic source. +

+

MCL_WAIT_EVENT_END_RX: + +
+wait the end of reception (i.e. once enough symbols have been +received to decode all objects) or until the MCL session +has received a ``CLOSE'' message from the traffic source. +Only valid at a receiver. +

+

MCL_WAIT_EVENT_CLOSED: + +
+wait untill a +CLOSE + +message has been received, meaning that no symbol will ever been +sent for this session. +

+Using +MCL_WAIT_EVENT_CLOSED + +requires that a +MCL_OPT_NEVER_LEAVE_BASE_LAYER + +(see mcl_ctl(3) manual) has been issued at the session start. +Indeed, +CLOSE + +messages are sent on the base layer and without this option +the receiver leaves the base layer once all objects have been +successfully decoded. +

+

+

+  +

RETURN VALUE

+ +

+On success returns 0, on error a non-zero value. +

+

+  +

EXAMPLE

+ +

+Here is a simple example. +

+

+        int     err = 0;
+
+        if ((err = mcl_wait_event(id, MCL_WAIT_EVENT_END_TX)) < 0) {
+                printf("ERROR: mcl_wait_event failed);
+                exit(-1);
+        }
+
+ +

+

+  +

COPYRIGHTS

+ +

+

+Copyright (c) 1999-2003 INRIA - Universite Paris 6 -
+All rights reserved
+(main author: Vincent Roca - vincent.roca@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ +

+

+  +

SEE ALSO

+ +

+mcl_open(), + +MCL + +documentation +

+

+  +

AUTHORS

+ +

+Vincent Roca (INRIA Rhone-Alpes, Planete project) +

+$Id: mcl_wait_event.man.3,v 1.2 2003/11/28 10:05:31 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
RETURN VALUE
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/mclrecv2.man.1 b/man/mclrecv2.man.1 new file mode 100644 index 0000000..94663b6 --- /dev/null +++ b/man/mclrecv2.man.1 @@ -0,0 +1,170 @@ +.\" Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH MCLRECV2 "1" "" "MCLv3 Reference Manual" + + +.SH NAME + +mclrecv2 \- receives a single file using the MultiCast Library (MCL) + + +.SH SYNOPSIS + +.B mclrecv2 +.nh +[\fB-h\fP[\fBelp\fP]] +[\fB-a address\fP[\fB/port\fP] +[\fB-l nb_of_layers\fP] +[\fB-p rx_profile\fP] +[\fB-v verbosity_level\fP] +[\fB-m stripping_mode_flag\fP] +.hy + + +.SH DESCRIPTION + +.B mclrecv2 +is meant to easily test all the advanced features of the MultiCast library +(MCL). +It is a simplified multicast file transfer tool that is used along with +.B mclsend2 . +Compared to the +.B fcast +multicast file transfer tool, it has limited possibilities (e.g. there +is no recursive mode, no attribute is communicated along with the file, +there is no checksum). +Less efforts have also been spent on the tool conviviality (e.g. +concerning the argument names). +But +.B mclsend2 / +.B mclrecv2 +are extremely valuable to test and compare many advanced features of the +MCL library as the user controls many (usually hidden) parameters. + + +.SH OPTIONS + +The following arguments can be provided. + +.TP +.B \-a address[/port] +Specifies the unicast or multicast address of the base layer (and its UDP +port number). +.I (communicated to MCL) +If no +.B -a +and/or +.B /port +argument is provided, then the default target address and port number of +MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port). +.I (communicated to MCL) + +.TP +.B \-h[elp] +Short help. Gives the credits and all the possible arguments. + +.TP +.B \-l number_of_layers +Specifies the number of layers to use in MCL. +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.TP +.B \-m stripping_mode_flag +Specifies if stripping should be used (value of 1, the default) +or not (value of 0). +Stripping a file means that this latter is split into multiple +independent fragments before being submitted to MCL. + +.I WARNING: is stripping mode is set in mclsend2, then it must also be set in mclrecv2! + +.TP +.B \-p rx_profile +Specifies the reception profile. +Possible values are today: +0 (LOW_RATE_INTERNET), 1 (MID_RATE_INTERNET), and 2 (HIGH_SPEED_LAN). +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception profiles match (some parameters like the LCT symbol size are not automatically communicated in the current version of MCL). + +.TP +.B \-v verbosity_level +Specifies the level of verbosity desired. +.I (communicated to MCL) + + +.SH RETURN VALUE + +The received file is written to a temporary file, usually +"/tmp/mclftp_xxxx" where "xxxx" is automatically replaced by a locally +unique sequence number. It is left to the user to remove this file or +rename it. + +On success returns 0. + + +.SH EXAMPLE + +Here is a simple example. +Traces are produced for each symbol received: + +.nf +mclrecv2 -v1 -a230.1.2.3/2323 +.fi + +A more complex example is the following: + +.nf +mclrecv2 -a230.1.2.3/2323 -v1 -m1 +.fi + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2002 INRIA - Universite Paris 6 - +All rights reserved +(main author: Vincent Roca - vincent.roca@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR mclsend2 (1), +.BR fcast (1), +.BR mcl_ctl (3), +.BR MCL +documentation + + +.SH AUTHORS + +Vincent Roca (INRIA Rhone-Alpes, Planete project) + +$Id: mclrecv2.man.1,v 1.2 2003/10/27 09:55:47 roca Exp $ diff --git a/man/mclrecv2.man.1.html b/man/mclrecv2.man.1.html new file mode 100644 index 0000000..e17fb8b --- /dev/null +++ b/man/mclrecv2.man.1.html @@ -0,0 +1,228 @@ +Content-type: text/html + +Manpage of MCLRECV2 + +

MCLRECV2

+Section: Misc. Reference Manual Pages (1)
Updated:
Index +Return to Main Contents
+ +

+

+  +

NAME

+ +

+mclrecv2 - receives a single file using the MultiCast Library (MCL) +

+

+  +

SYNOPSIS

+ +

+mclrecv2 + + +[-h[elp]] +[-a address[/port] +[-l nb_of_layers] +[-p rx_profile] +[-v verbosity_level] +[-m stripping_mode_flag] + +

+

+  +

DESCRIPTION

+ +

+mclrecv2 + +is meant to easily test all the advanced features of the MultiCast library +(MCL). +It is a simplified multicast file transfer tool that is used along with +mclsend2 . + +Compared to the +fcast + +multicast file transfer tool, it has limited possibilities (e.g. there +is no recursive mode, no attribute is communicated along with the file, +there is no checksum). +Less efforts have also been spent on the tool conviviality (e.g. +concerning the argument names). +But +mclsend2 / + +mclrecv2 + +are extremely valuable to test and compare many advanced features of the +MCL library as the user controls many (usually hidden) parameters. +

+

+  +

OPTIONS

+ +

+The following arguments can be provided. +

+

+
-a address[/port] + +
+Specifies the unicast or multicast address of the base layer (and its UDP +port number). +(communicated to MCL) + +If no +-a + +and/or +/port + +argument is provided, then the default target address and port number of +MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port). +(communicated to MCL) + +

+

-h[elp] + +
+Short help. Gives the credits and all the possible arguments. +

+

-l number_of_layers + +
+Specifies the number of layers to use in MCL. +If not specified, the default value of MCL is used instead. +(communicated to MCL) + +

+

-m stripping_mode_flag + +
+Specifies if stripping should be used (value of 1, the default) +or not (value of 0). +Stripping a file means that this latter is split into multiple +independent fragments before being submitted to MCL. +

+WARNING: is stripping mode is set in mclsend2, then it must also be set in mclrecv2! + +

+

-p rx_profile + +
+Specifies the reception profile. +Possible values are today: +0 (LOW_RATE_INTERNET), 1 (MID_RATE_INTERNET), and 2 (HIGH_SPEED_LAN). +If not specified, the default value of MCL is used instead. +(communicated to MCL) + +

+WARNING: it is important that the transmission and reception profiles match (some parameters like the LCT symbol size are not automatically communicated in the current version of MCL). + +

+

-v verbosity_level + +
+Specifies the level of verbosity desired. +(communicated to MCL) + +

+

+

+  +

RETURN VALUE

+ +

+The received file is written to a temporary file, usually +"/tmp/mclftp_xxxx" where "xxxx" is automatically replaced by a locally +unique sequence number. It is left to the user to remove this file or +rename it. +

+On success returns 0. +

+

+  +

EXAMPLE

+ +

+Here is a simple example. +Traces are produced for each symbol received: +

+

+mclrecv2 -v1 -a230.1.2.3/2323
+
+ +

+A more complex example is the following: +

+

+mclrecv2 -a230.1.2.3/2323 -v1 -m1
+
+ +

+

+  +

COPYRIGHTS

+ +

+

+Copyright (c) 1999-2002 INRIA - Universite Paris 6 -
+All rights reserved
+(main author: Vincent Roca - vincent.roca@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ +

+

+  +

SEE ALSO

+ +

+mclsend2(1), + +fcast(1), + +mcl_ctl(3), + +MCL + +documentation +

+

+  +

AUTHORS

+ +

+Vincent Roca (INRIA Rhone-Alpes, Planete project) +

+$Id: mclrecv2.man.1,v 1.2 2003/10/27 09:55:47 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
OPTIONS
+
RETURN VALUE
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/man/mclsend2.man.1 b/man/mclsend2.man.1 new file mode 100644 index 0000000..711dd00 --- /dev/null +++ b/man/mclsend2.man.1 @@ -0,0 +1,219 @@ +.\" Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved +.\" (main author: Vincent Roca - vincent.roca@inrialpes.fr) +.\" +.\" This program is free software; you can redistribute it and/or +.\" modify it under the terms of the GNU General Public License +.\" as published by the Free Software Foundation; either version 2 +.\" of the License, or (at your option) any later version. +.\" +.\" This program is distributed in the hope that it will be useful, +.\" but WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public License +.\" along with this program; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, +.\" USA. + + +.TH MCLSEND2 "1" "" "MCLv3 Reference Manual" + + +.SH NAME + +mclsend2 \- send a single file using the MultiCast Library (MCL) + + +.SH SYNOPSIS + +.B mclsend2 +.nh +[\fB-h\fP[\fBelp\fP]] +[\fB-a address\fP[\fB/port\fP] +[\fB-l nb_of_layers\fP] +[\fB-p tx_profile\fP] +[\fB-v verbosity_level\fP] +[\fB-c\fP] +[\fB-f fec_ratio\fP] +[\fB-t ttl\fP] +[\fB-m stripping_mode_flag\fP] +[\fB-k keep_push_mode_flag\fP] +[\fB-s lct_sched\fP] +[\fB-S object_sched\fP] +.hy + + +.SH DESCRIPTION + +.B mclsend2 +is meant to easily test all the advanced features of the MultiCast library +(MCL). +It is a simplified multicast file transfer tool that is used along with +.B mclrecv2 . +Compared to the +.B fcast +multicast file transfer tool, it has limited possibilities (e.g. there +is no recursive mode, no attribute is communicated along with the file, +there is no checksum). +Less efforts have also been spent on the tool conviviality (e.g. +concerning the argument names). +But +.B mclsend2 / +.B mclrecv2 +are extremely valuable to test and compare many advanced features of the +MCL library as the user controls many (usually hidden) parameters. + + +.SH OPTIONS + +The following arguments can be provided. + +.TP +.B \-a address[/port] +Specifies the unicast or multicast address of the base layer (and its UDP +port number). +.I (communicated to MCL) +If no +.B -a +and/or +.B /port +argument is provided, then the default target address and port number of +MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port). +.I (communicated to MCL) + +.TP +.B \-c +Set the +.I continuous mode +for "on-demand" transmissions (e.g. transmissions where receivers arrive +at their discretion, download the file and leave). +By default it is not set. +.I (communicated to MCL) + +.TP +.B \-f fec_ratio +Specifies the FEC ratio (a floating point number) to use. +This ratio is given by nb_of_data_symbols / total_nb_of_symbols, +so a fec_ratio of 1.0 means no FEC at all, +a fec_ratio of 2.0 means "as many FEC symbols as there are data symbols", etc. +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.TP +.B \-h[elp] +Short help. Gives the credits and all the possible arguments. + +.TP +.B \-k keep_push_mode_flag +Specifies if the keep/push mode should be used (value of 1, the default) +or not (value of 0). +This parameter is only meaningful in stripping mode. +.I (communicated to MCL) + +.TP +.B \-l number_of_layers +Specifies the number of layers to use in MCL. +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.TP +.B \-m stripping_mode_flag +Specifies if stripping should be used (value of 1, the default) +or not (value of 0). +Stripping a file means that this latter is splitted into multiple +independent fragments before being submitted to MCL. + +.I WARNING: if stripping mode is set in mclsend2, then it must also be set in mclrecv2! + +.TP +.B \-p tx_profile +Specifies the transmission profile. +Possible values are today: +0 (LOW_RATE_INTERNET), 1 (MID_RATE_INTERNET), and 2 (HIGH_SPEED_LAN). +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.I WARNING: it is important that the transmission and reception profiles match (some parameters like the LCT symbol size are not automatically communicated in the current version of MCL). + +.TP +.B \-S obj_sched +Specifies the object scheduler (i.e. in stripping mode, in what order should +the objects be scheduled on the various layers). +Currently one can choose +0 (SEQUENTIAL_OBJ_ORDER), 1 (RANDOM_OBJ_ORDER), 2 (PARTIALLY_MIXED_ORDER) +or 3 (MIXED_ORDER). +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.TP +.B \-s lct_sched +Specifies the symbol scheduler (i.e. what symbols to send on what layer) +to use. +Currently one can choose either 0 (send the same symbols on each layer) +or 1 (send data on the base layer, a first set of FEC symbols on layer 1, +a second set of FEC symbols on layer 2, etc.). +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.TP +.B \-t ttl +Specifies the time to live (ttl) value of the IP header. +If not specified, the default value of MCL is used instead. +.I (communicated to MCL) + +.TP +.B \-v verbosity_level +Specifies the level of verbosity desired. +.I (communicated to MCL) + + +.SH EXAMPLE + +Here is a simple example where the file "/tmp/file_to_send" is sent +using the MCL defaults on group 230.1.2.3 and above. +Traces are produced for each object (if the file is stripped) and each +packet sent: + +.nf +mclsend2 -v1 -a230.1.2.3/2323 /tmp/file_to_send +.fi + +A more complex example is the following: + +.nf +mclsend2 -a230.1.2.3/2323 -v1 -m1 -s1 -S3 /tmp/mclsend2.man +.fi + + +.SH COPYRIGHTS + +.nf +Copyright (c) 1999-2002 INRIA - Universite Paris 6 - +All rights reserved +(main author: Vincent Roca - vincent.roca@inrialpes.fr) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. +.fi + + +.SH SEE ALSO + +.BR mclrecv2 (1), +.BR fcast (1), +.BR mcl_ctl (3), +.BR MCL +documentation + + +.SH AUTHORS + +Vincent Roca (INRIA Rhone-Alpes, Planete project) + +$Id: mclsend2.man.1,v 1.2 2003/10/27 09:55:47 roca Exp $ diff --git a/man/mclsend2.man.1.html b/man/mclsend2.man.1.html new file mode 100644 index 0000000..ee392f0 --- /dev/null +++ b/man/mclsend2.man.1.html @@ -0,0 +1,287 @@ +Content-type: text/html + +Manpage of MCLSEND2 + +

MCLSEND2

+Section: Misc. Reference Manual Pages (1)
Updated:
Index +Return to Main Contents
+ +

+

+  +

NAME

+ +

+mclsend2 - send a single file using the MultiCast Library (MCL) +

+

+  +

SYNOPSIS

+ +

+mclsend2 + + +[-h[elp]] +[-a address[/port] +[-l nb_of_layers] +[-p tx_profile] +[-v verbosity_level] +[-c] +[-f fec_ratio] +[-t ttl] +[-m stripping_mode_flag] +[-k keep_push_mode_flag] +[-s lct_sched] +[-S object_sched] + +

+

+  +

DESCRIPTION

+ +

+mclsend2 + +is meant to easily test all the advanced features of the MultiCast library +(MCL). +It is a simplified multicast file transfer tool that is used along with +mclrecv2 . + +Compared to the +fcast + +multicast file transfer tool, it has limited possibilities (e.g. there +is no recursive mode, no attribute is communicated along with the file, +there is no checksum). +Less efforts have also been spent on the tool conviviality (e.g. +concerning the argument names). +But +mclsend2 / + +mclrecv2 + +are extremely valuable to test and compare many advanced features of the +MCL library as the user controls many (usually hidden) parameters. +

+

+  +

OPTIONS

+ +

+The following arguments can be provided. +

+

+
-a address[/port] + +
+Specifies the unicast or multicast address of the base layer (and its UDP +port number). +(communicated to MCL) + +If no +-a + +and/or +/port + +argument is provided, then the default target address and port number of +MCL are used. +With multicast addresses, the address and port number of layers 1 and above +are derived from that of the base layer by MCL (usually by incrementing the +address and port). +(communicated to MCL) + +

+

-c + +
+Set the +continuous mode + +for "on-demand" transmissions (e.g. transmissions where receivers arrive +at their discretion, download the file and leave). +By default it is not set. +(communicated to MCL) + +

+

-f fec_ratio + +
+Specifies the FEC ratio (a floating point number) to use. +This ratio is given by nb_of_data_symbols / total_nb_of_symbols, +so a fec_ratio of 1.0 means no FEC at all, +a fec_ratio of 2.0 means "as many FEC symbols as there are data symbols", etc. +If not specified, the default value of MCL is used instead. +(communicated to MCL) + +

+

-h[elp] + +
+Short help. Gives the credits and all the possible arguments. +

+

-k keep_push_mode_flag + +
+Specifies if the keep/push mode should be used (value of 1, the default) +or not (value of 0). +This parameter is only meaningful in stripping mode. +(communicated to MCL) + +

+

-l number_of_layers + +
+Specifies the number of layers to use in MCL. +If not specified, the default value of MCL is used instead. +(communicated to MCL) + +

+

-m stripping_mode_flag + +
+Specifies if stripping should be used (value of 1, the default) +or not (value of 0). +Stripping a file means that this latter is splitted into multiple +independent fragments before being submitted to MCL. +

+WARNING: if stripping mode is set in mclsend2, then it must also be set in mclrecv2! + +

+

-p tx_profile + +
+Specifies the transmission profile. +Possible values are today: +0 (LOW_RATE_INTERNET), 1 (MID_RATE_INTERNET), and 2 (HIGH_SPEED_LAN). +If not specified, the default value of MCL is used instead. +(communicated to MCL) + +

+WARNING: it is important that the transmission and reception profiles match (some parameters like the LCT symbol size are not automatically communicated in the current version of MCL). + +

+

-S obj_sched + +
+Specifies the object scheduler (i.e. in stripping mode, in what order should +the objects be scheduled on the various layers). +Currently one can choose +0 (SEQUENTIAL_OBJ_ORDER), 1 (RANDOM_OBJ_ORDER), 2 (PARTIALLY_MIXED_ORDER) +or 3 (MIXED_ORDER). +If not specified, the default value of MCL is used instead. +(communicated to MCL) + +

+

-s lct_sched + +
+Specifies the symbol scheduler (i.e. what symbols to send on what layer) +to use. +Currently one can choose either 0 (send the same symbols on each layer) +or 1 (send data on the base layer, a first set of FEC symbols on layer 1, +a second set of FEC symbols on layer 2, etc.). +If not specified, the default value of MCL is used instead. +(communicated to MCL) + +

+

-t ttl + +
+Specifies the time to live (ttl) value of the IP header. +If not specified, the default value of MCL is used instead. +(communicated to MCL) + +

+

-v verbosity_level + +
+Specifies the level of verbosity desired. +(communicated to MCL) + +

+

+

+  +

EXAMPLE

+ +

+Here is a simple example where the file "/tmp/file_to_send" is sent +using the MCL defaults on group 230.1.2.3 and above. +Traces are produced for each object (if the file is stripped) and each +packet sent: +

+

+mclsend2 -v1 -a230.1.2.3/2323 /tmp/file_to_send
+
+ +

+A more complex example is the following: +

+

+mclsend2 -a230.1.2.3/2323 -v1 -m1 -s1 -S3 /tmp/mclsend2.man
+
+ +

+

+  +

COPYRIGHTS

+ +

+

+Copyright (c) 1999-2002 INRIA - Universite Paris 6 -
+All rights reserved
+(main author: Vincent Roca - vincent.roca@inrialpes.fr)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+ +

+

+  +

SEE ALSO

+ +

+mclrecv2(1), + +fcast(1), + +mcl_ctl(3), + +MCL + +documentation +

+

+  +

AUTHORS

+ +

+Vincent Roca (INRIA Rhone-Alpes, Planete project) +

+$Id: mclsend2.man.1,v 1.2 2003/10/27 09:55:47 roca Exp $ +

+ +


+ 

Index

+
+
NAME
+
SYNOPSIS
+
DESCRIPTION
+
OPTIONS
+
EXAMPLE
+
COPYRIGHTS
+
SEE ALSO
+
AUTHORS
+
+
+This document was created by +man2html, +using the manual pages.
+Time: 07:30:02 GMT, May 25, 2005 + + diff --git a/mclftp/Makefile b/mclftp/Makefile new file mode 100644 index 0000000..9c02ece --- /dev/null +++ b/mclftp/Makefile @@ -0,0 +1,188 @@ +# $Id: Makefile,v 1.29 2005/01/11 13:12:24 roca Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../Makefile.common + + +# libraries required +ifeq (${OS},linux) + # Linux version + # MCL library requires -lpthread + # add MPATROL support if required + # + BINDIR = ../bin/linux + LIBRARIES = -lc -lm -lpthread +endif + +ifeq (${OS},solaris) + # Solaris version: requires -lsocket -lnsl and -L/usr/ucblib -lucb + # nb: to avoid LD_LIBRARY_PATH problems, specify /usr/ucblib/libucb.a + # directly and use the static version! + # + BINDIR = ../bin/solaris + #LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -lpthread + LIBRARIES = -lc -lm -lsocket -lnsl /usr/ucblib/libucb.a -lposix4 -lpthread +endif + +ifeq (${OS},freebsd) + # FreeBSD version + # MCL library requires -pthread + # + BINDIR = ../bin/freebsd + LIBRARIES = -lm -pthread +endif + + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc additional compilation flags +# -g to create additional debug info used by the gdb debugger +# -static to avoid dynamic libraries +# -pg for profiling with gprof +# +CFLAGS = -O -g ${OSFLAGS} -D${RM_PROTOCOL} +#CFLAGS = -O -g ${OSFLAGS} -D${RM_PROTOCOL} -pg +#CFLAGS = -O -g ${OSFLAGS} -D${RM_PROTOCOL} -static + +# add purify linker for memory debug (Solaris only). +# Purify 4.0 Solaris 2, Copyright (C) 1992-1996 Pure Software Inc. +# +#CCLINK_PURE = purify ${CC} +#CCLINK_PURE = purify -cache-dir=${HOME}/pcache ${CC} +CCLINK_PURE = purify -cache-dir=/tmp ${CC} +# to use pufigy, you only need to uncomment the following line which +# overrides ${CC}! +#${CC} = ${CCLINK_PURE} + +#SRCFILES = mclrecv.c mclsend.c mclrecv2.c mclsend2.c +SRCFILES = mclrecv.c mclsend.c +OFILES = ${SRCFILES:.c=.o} + + +###### choose between the ALC / NORM versions ###### + +# compile either with ALC or NORM support. +# the RM_PROTOCOL and MCL_LIBRARY variables are target-specific + +alc: RM_PROTOCOL = ALC +alc: MCL_LIBRARY = ${BINDIR}/libmclalc.a +alc: all + +norm: RM_PROTOCOL = NORM +norm: MCL_LIBRARY = ${BINDIR}/libmclnorm.a +norm: all + + +###### Dependancies ###### + +#all: ${BINDIR}/mclrecv ${BINDIR}/mclsend ${BINDIR}/mclrecv2 ${BINDIR}/mclsend2 +all: ${BINDIR}/mclsend ${BINDIR}/mclrecv + +${BINDIR}/mclsend: mclsend.o ${MCL_LIBRARY} + @echo "** Compile mclsend using the MCL-${RM_PROTOCOL} library ${MCL_LIBRARY}..." + #${CCLINK_PURE} ${CFLAGS} mclsend.o ${LIBRARIES} ${MCL_LIBRARY} -o ${BINDIR}/mclsend + ${CC} ${CFLAGS} mclsend.o ${LIBRARIES} ${MCL_LIBRARY} -o ${BINDIR}/mclsend + +${BINDIR}/mclrecv: mclrecv.o ${MCL_LIBRARY} + @echo "** Compile mclrecv using the MCL-${RM_PROTOCOL} library ${MCL_LIBRARY}..." + #${CCLINK_PURE} ${CFLAGS} mclrecv.o ${LIBRARIES} ${MCL_LIBRARY} -o ${BINDIR}/mclrecv + ${CC} ${CFLAGS} mclrecv.o ${LIBRARIES} ${MCL_LIBRARY} -o ${BINDIR}/mclrecv + +#${BINDIR}/mclsend2: mclsend2.o ${MCL_LIBRARY} +# @echo "** Compile mclsend2 using the MCL-${RM_PROTOCOL} library..." +# ${CC} ${CFLAGS} mclsend2.o ${LIBRARIES} ${MCL_LIBRARY} -o ${BINDIR}/mclsend2 + +#${BINDIR}/mclrecv2: mclrecv2.o ${MCL_LIBRARY} +# @echo "** Compile mclrecv using the MCL-${RM_PROTOCOL} library..." +# ${CC} ${CFLAGS} mclrecv2.o ${LIBRARIES} ${MCL_LIBRARY} -o ${BINDIR}/mclrecv2 + + +clean : + @for f in core ${BINDIR}/core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in ${BINDIR}/mclsend ${BINDIR}/mclrecv ${BINDIR}/mclsend2 ${BINDIR}/mclrecv2 ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +mclrecv.o: mclftp.h /usr/include/stdio.h /usr/include/features.h +mclrecv.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +mclrecv.o: /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h +mclrecv.o: /usr/include/bits/types.h /usr/include/bits/wordsize.h +mclrecv.o: /usr/include/bits/typesizes.h /usr/include/libio.h +mclrecv.o: /usr/include/_G_config.h /usr/include/wchar.h +mclrecv.o: /usr/include/bits/wchar.h /usr/include/gconv.h +mclrecv.o: /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h +mclrecv.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h +mclrecv.o: /usr/include/stdlib.h /usr/include/errno.h +mclrecv.o: /usr/include/bits/errno.h /usr/include/linux/errno.h +mclrecv.o: /usr/include/asm/errno.h /usr/include/ctype.h +mclrecv.o: /usr/include/endian.h /usr/include/bits/endian.h +mclrecv.o: /usr/include/string.h /usr/include/sys/types.h /usr/include/time.h +mclrecv.o: /usr/include/sys/stat.h /usr/include/bits/stat.h +mclrecv.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h +mclrecv.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h +mclrecv.o: /usr/include/bits/confname.h /usr/include/netdb.h +mclrecv.o: /usr/include/netinet/in.h /usr/include/stdint.h +mclrecv.o: /usr/include/sys/socket.h /usr/include/sys/uio.h +mclrecv.o: /usr/include/bits/uio.h /usr/include/bits/socket.h +mclrecv.o: /usr/include/limits.h +mclrecv.o: /usr/lib/gcc/i386-redhat-linux/3.4.2/include/limits.h +mclrecv.o: /usr/include/bits/sockaddr.h /usr/include/asm/socket.h +mclrecv.o: /usr/include/asm/sockios.h /usr/include/bits/in.h +mclrecv.o: /usr/include/bits/byteswap.h /usr/include/bits/netdb.h +mclrecv.o: /usr/include/arpa/inet.h ../src/common/mcl_lib_api.h +mclrecv.o: ../src/common/mcl_types.h +mclsend.o: mclftp.h /usr/include/stdio.h /usr/include/features.h +mclsend.o: /usr/include/sys/cdefs.h /usr/include/gnu/stubs.h +mclsend.o: /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stddef.h +mclsend.o: /usr/include/bits/types.h /usr/include/bits/wordsize.h +mclsend.o: /usr/include/bits/typesizes.h /usr/include/libio.h +mclsend.o: /usr/include/_G_config.h /usr/include/wchar.h +mclsend.o: /usr/include/bits/wchar.h /usr/include/gconv.h +mclsend.o: /usr/lib/gcc/i386-redhat-linux/3.4.2/include/stdarg.h +mclsend.o: /usr/include/bits/stdio_lim.h /usr/include/bits/sys_errlist.h +mclsend.o: /usr/include/stdlib.h /usr/include/errno.h +mclsend.o: /usr/include/bits/errno.h /usr/include/linux/errno.h +mclsend.o: /usr/include/asm/errno.h /usr/include/ctype.h +mclsend.o: /usr/include/endian.h /usr/include/bits/endian.h +mclsend.o: /usr/include/string.h /usr/include/sys/types.h /usr/include/time.h +mclsend.o: /usr/include/sys/stat.h /usr/include/bits/stat.h +mclsend.o: /usr/include/fcntl.h /usr/include/bits/fcntl.h +mclsend.o: /usr/include/unistd.h /usr/include/bits/posix_opt.h +mclsend.o: /usr/include/bits/confname.h /usr/include/netdb.h +mclsend.o: /usr/include/netinet/in.h /usr/include/stdint.h +mclsend.o: /usr/include/sys/socket.h /usr/include/sys/uio.h +mclsend.o: /usr/include/bits/uio.h /usr/include/bits/socket.h +mclsend.o: /usr/include/limits.h +mclsend.o: /usr/lib/gcc/i386-redhat-linux/3.4.2/include/limits.h +mclsend.o: /usr/include/bits/sockaddr.h /usr/include/asm/socket.h +mclsend.o: /usr/include/asm/sockios.h /usr/include/bits/in.h +mclsend.o: /usr/include/bits/byteswap.h /usr/include/bits/netdb.h +mclsend.o: /usr/include/arpa/inet.h ../src/common/mcl_lib_api.h +mclsend.o: ../src/common/mcl_types.h diff --git a/mclftp/mclftp.h b/mclftp/mclftp.h new file mode 100644 index 0000000..bd9b85a --- /dev/null +++ b/mclftp/mclftp.h @@ -0,0 +1,80 @@ +/* $Id: mclftp.h,v 1.1.1.1 2003/09/03 12:45:43 chneuman Exp $ */ +/* + * Copyright (c) 2002 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include +#include +#include + +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#include "getopt.h" +#else +#include +#include +#include +#include +#include +#endif /* OS_DEP */ + +#include "../src/common/mcl_lib_api.h" + + +/* send/recv buffer size */ +#define BUFLEN 31744 /* 32768-1024 to keep room for 4 offset bytes */ +/*#define BUFLEN 32768*/ +/*#define BUFLEN 16384*/ + +/****** general macros ******/ + +/* + * print to stdout + */ +#define PRINT_OUT(a) { \ + fprintf a; \ + fflush(stdout); \ + } + +/* + * print and exit + */ +#define EXIT(a) { \ + printf a; \ + fflush(stdout); \ + exit(-1); \ + } + +#define ASSERT(c) { \ + if (!(c)) { \ + fprintf(stderr, "ASSERT [%s:%d] failed\n", \ + __FILE__, __LINE__); \ + fflush(stderr); \ + exit (-1); \ + } \ + } + diff --git a/mclftp/mclrecv.c b/mclftp/mclrecv.c new file mode 100644 index 0000000..91ccdbb --- /dev/null +++ b/mclftp/mclrecv.c @@ -0,0 +1,225 @@ +/* $Id: mclrecv.c,v 1.1.1.1 2003/09/03 12:45:43 chneuman Exp $ */ +/* + * Copyright (c) 2002 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * mclrecv.c + * + * Receiver side of the mini FTP over MCL tool. + * This example shows how to use the MCL library. + * It remains exactly the same while changing the + * internal MCL library algorithms (scheduling, + * reliability, etc.) + */ + +#include "mclftp.h" + +void mclget (void); +void parse_commandline (int argc, char *argv[]); +void mclget_usage (int argc, char *argv[]); + + +int fd; /* input file fd */ +int id = 0; /* mcl endpoint fd */ +int verbose = -1; +#ifdef ALC +int layers = 0; +#endif +int port = 2324; +unsigned long addr = 0; + + +int +main (int argc, + char *argv[]) +{ + parse_commandline(argc, argv); + mclget(); + exit(0); +} + + +/* + * serious stuff is here; not too complex, isn't it? + * NB: assumes an ordered delivery service !!! + */ +void +mclget (void) +{ + int len; + char buf[BUFLEN]; + int received = 0; /* total number of bytes received */ + + /* open as a sender... */ + if ((id = mcl_open("r")) < 0) + EXIT(("mclget: mcl_open failed\n")) + /* specify a few important parameters... */ + if (verbose >= 0) { + int stats = 2; /* 2 => all intermediate stats */ + mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose,sizeof(verbose)); + mcl_ctl(id, MCL_OPT_STATS, (void*)&stats, sizeof(stats)); + } +#ifdef ALC + if (layers >= 0) + mcl_ctl(id, MCL_OPT_LAYER_NB, (void*)&layers, sizeof(layers)); +#endif + if (port > 0) /* in host format! */ + mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (addr > 0) /* in host format! */ + mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + /* get the file content... */ + while ((len = mcl_recv(id, buf, BUFLEN)) > 0) { + write(fd, buf, len); + received += len; + PRINT_OUT((stdout, "mclget: %d bytes read, total=%d\n", len, received)) + } + PRINT_OUT((stdout, "mclget: %d bytes received\n", received)) + /* close... */ + mcl_close(id); + /* ... and that's all folks */ +} + + +void +parse_commandline (int argc, + char *argv[]) +{ + int c; + char filename[256]; +#ifdef SOLARIS + extern char *optarg; +#elif defined(WIN32) + char *optarg = NULL; +#endif +#ifdef ALC + const char *getopt_string = "a:v:l:h"; +#else + const char *getopt_string = "a:v:h"; +#endif + +#ifdef WIN32 + strncpy(filename, tempnam(".\\", "mclftp."), 256); +#else + sprintf(filename, "/tmp/mclftp_%d", (int)getpid()); +#endif /* OS_DEP */ + + PRINT_OUT((stdout, "mclget: output file is %s\n", filename)) + +#ifdef WIN32 + if ((fd = open( filename, O_WRONLY | O_CREAT | O_BINARY, _S_IWRITE) ) < 0) +#else + if ((fd = open( filename, O_WRONLY | O_CREAT, S_IRWXU)) < 0) +#endif + { + perror("Error : "); + EXIT(("Error while opening file \"%s\"\n", filename)) + } + +#ifdef WIN32 + while ((c = GetOption(argc, argv, getopt_string, &optarg)) != 0) +#else + + while ((c = getopt(argc, argv, getopt_string)) != EOF) +#endif + { + switch (c) { + case 'a': + if (*optarg) { + /* process addr/port argument */ + char rname[128]; /* remote name string */ + char *p; + + strncpy(rname, optarg, sizeof(rname)); + if ((p = strchr(rname, '/')) != NULL) { + *p = '\0'; + /* in host order */ + port = (unsigned short)atoi(p+1); + } + /* + * addr must be in host byte order, but + * gethostbyname/inet_addr return network order + */ + if (isalpha((int)rname[0])) { + if (gethostbyname(rname) == NULL) + EXIT(("unknown host ""%s""\n", rname)) + addr = ntohl(*(unsigned long *) + (gethostbyname(rname)->h_addr)); + } else + addr = ntohl(inet_addr(rname)); + } else + EXIT(( "bad argument -a%s\n", optarg)) + break; + case 'v': /* verbosity level */ + if (isdigit((int)*optarg)) + verbose = atoi(optarg); + else + EXIT(("bad argument -v%s\n", optarg)) + break; +#ifdef ALC + case 'l': /* number of layers */ + if (isdigit((int)*optarg)) + layers = atoi(optarg); + else + EXIT(("bad argument -l%s\n", optarg)) + break; +#endif + case 'h': + mclget_usage(argc, argv); + default: + /* + * NB: getopt returns '?' when finding an + * unknown argument; avoid the following + * error msg in that case + */ + if (c != '?') + PRINT_OUT((stdout, "bad argument %c\n", c)) + mclget_usage(argc, argv); + } + } +} + + +void +mclget_usage (int argc, + char *argv[]) +{ + if (id == 0) { /* need an MCL endpoint first */ + if ((id = mcl_open("r")) < 0) + EXIT(("mclget_usage: mcl_open failed\n")) + } + mcl_ctl(id, MCL_OPT_MOREABOUT, NULL, 0); + + PRINT_OUT((stdout, "\n\nUsage: %s [options]\n", argv[0])) + +#ifdef WIN32 + PRINT_OUT((stdout, " Receive and save a file in .\\mclftp* where '*' is an unique suffix\n")) +#else + PRINT_OUT((stdout, " Receive and save a file in /tmp/mclfile_`pid`\n")) +#endif + + PRINT_OUT((stdout, " -h[elp] this help\n")) + PRINT_OUT((stdout, " -an[/p] set uni/multicast address or name to n and\n")) + PRINT_OUT((stdout, " port number to p (default 127.0.0.1/%d)\n", port)) +#ifdef ALC + PRINT_OUT((stdout, " -ln set number of layers to n\n")) +#endif + PRINT_OUT((stdout, " -vn set verbosity level to n\n")) + exit(0); +} diff --git a/mclftp/mclsend.c b/mclftp/mclsend.c new file mode 100644 index 0000000..0603530 --- /dev/null +++ b/mclftp/mclsend.c @@ -0,0 +1,212 @@ +/* $Id: mclsend.c,v 1.1.1.1 2003/09/03 12:45:43 chneuman Exp $ */ +/* + * Copyright (c) 2002 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * mclsend.c + * + * Sender (deamon) side of the mini FTP over MCL tool + * This example shows how to use the MCL library. + * It remains exactly the same while changing the + * internal MCL library algorithms (scheduling, + * reliability, etc.) + */ + +#include "mclftp.h" + +void send (void); +void parse_commandline (int argc, char *argv[]); +void usage (int argc, char *argv[]); + + +int fd; /* input file fd */ +int id = 0; /* mcl endpoint fd */ +int verbose = -1; +int port = 2324; +unsigned long addr = 0; +int ttl = 5; +#ifdef ALC +int layer = 8; +#endif + + +int +main (int argc, + char *argv[]) +{ + parse_commandline(argc, argv); + send(); +#ifdef WIN32 + WSACleanup(); +#endif + exit(0); +} + + +/* + * serious stuff is here; not too complex, isn't it? + * NB: assumes an ordered delivery service !!! + */ +void +send (void) +{ + int len; + char buf[BUFLEN]; + int sent = 0; /* total number of bytes sent */ + + /* open as a sender... */ + if ((id = mcl_open("w")) < 0) + EXIT(("send: mcl_open failed\n")) + /* specify a few important parameters... */ + if (verbose >= 0) { + int stats = 1; /* 1 => all intermediate stats */ + mcl_ctl(id, MCL_OPT_VERBOSITY, (void*)&verbose,sizeof(verbose)); + mcl_ctl(id, MCL_OPT_STATS, (void*)&stats, sizeof(int)); + } + if (port > 0) /* in host format! */ + mcl_ctl(id, MCL_OPT_PORT, (void*)&port, sizeof(port)); + if (addr > 0) /* in host format! */ + mcl_ctl(id, MCL_OPT_ADDR, (void*)&addr, sizeof(addr)); + if (ttl > 0) + mcl_ctl(id, MCL_OPT_TTL, (void*)&ttl, sizeof(ttl)); + +#ifdef ALC + if (layer > 0) + mcl_ctl(id, MCL_OPT_LAYER_NB, (void*)&layer, sizeof(layer)); +#endif + + /* send the file content... */ + while ((len = read(fd, buf, BUFLEN)) > 0) { + if (mcl_send(id, buf, len) < 0) + EXIT(("send: mcl_send %d failed\n", len)) + sent += len; + } + if (len < 0) + EXIT(("send: read failed, returned %d\n", len)) + PRINT_OUT((stdout, "send: %d bytes sent\n", sent)) + /* close... */ + mcl_close(id); + /* ... and that's all folks */ +} + + +void +parse_commandline (int argc, + char *argv[]) +{ + int c; +#ifdef SOLARIS + extern char *optarg; +#elif defined(WIN32) + char *optarg = NULL; +#endif + + if(argc<2) + usage(argc, argv); + + /* last arg is file name */ + ASSERT((argv[argc-1])) + if (strcmp(argv[argc-1], "-h") && strcmp(argv[argc-1], "-help") + && strcmp(argv[argc-1], "/h") && strcmp(argv[argc-1], "/?") ) + { + if ((fd = open(argv[argc-1], +#ifdef WIN32 + _O_BINARY | +#endif + O_RDONLY)) < 0) { + perror("Error while parsing command line: "); + EXIT(("Unable to open file \"%s\"\n", + argv[argc-1])) + } + argc--; + } +#ifdef WIN32 + while ((c = GetOption(argc, argv, "a:v:h", &optarg)) != 0) +#else + while ((c = getopt(argc, argv, "a:v:h")) != EOF) +#endif + { + switch (c) { + case 'a': + if (*optarg) { + /* process addr/port argument */ + char rname[128]; /* remote name string */ + char *p; + + strncpy(rname, optarg, sizeof(rname)); + if ((p = strchr(rname, '/')) != NULL) { + *p = '\0'; + /* in host order */ + port = (unsigned short)atoi(p+1); + } + /* + * addr must be in host byte order, but + * gethostbyname/inet_addr return network order + */ + if (isalpha((int)rname[0])) { + if (gethostbyname(rname) == NULL) + EXIT(("unknown host ""%s""\n", rname)) + addr = ntohl(*(unsigned long *) + (gethostbyname(rname)->h_addr)); + } else + addr = ntohl(inet_addr(rname)); + } else + EXIT(( "bad argument -a%s\n", optarg)) + break; + case 'v': /* verbosity level */ + if (isdigit((int)*optarg)) + verbose = atoi(optarg); + else + EXIT(("bad argument -v%s\n", optarg)) + break; + case 'h': + usage(argc, argv); + default: + /* + * NB: getopt returns '?' when finding an + * unknown argument; avoid the following + * error msg in that case + */ + if (c != '?') + PRINT_OUT((stdout, "bad argument %c\n", c)) + usage(argc, argv); + } + } +} + + +void +usage (int argc, + char *argv[]) +{ + if (id == 0) { /* need an MCL endpoint first */ + if ((id = mcl_open("w")) < 0) + EXIT(("usage: mcl_open failed\n")) + } + mcl_ctl(id, MCL_OPT_MOREABOUT, NULL, 0); + + PRINT_OUT((stdout, "\n\nUsage: %s [options] file_to_tx\n", argv[0])) + PRINT_OUT((stdout, " -h[elp] this help\n")) + + PRINT_OUT((stdout, " -an[/p] set uni/multicast address or name to n and\n")) + PRINT_OUT((stdout, " port number to p (default 127.0.0.1/%d)\n", port)) + PRINT_OUT((stdout, " -vn set verbosity level to n\n")) + exit(0); +} diff --git a/mclv3.sln b/mclv3.sln new file mode 100644 index 0000000..8137494 --- /dev/null +++ b/mclv3.sln @@ -0,0 +1,61 @@ +Microsoft Visual Studio Solution File, Format Version 7.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmclalc", "src\alc\libmclalc.vcproj", "{B42905F7-0F95-4E9B-9F50-F74EAA8C2105}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "fcast", "fcast\fcast.vcproj", "{EFA02B50-FACA-4736-8324-BAEEB9EED725}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "robcast_client", "robcast\robcast_client.vcproj", "{4D556DD8-A4A6-4C1A-99D7-614D498E86CA}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "robcast_server", "robcast\robcast_server.vcproj", "{4139BD27-57C0-434A-BA0E-E49AE4C50DDF}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sdp_lib", "src\sdp_lib\sdplib.vcproj", "{B42905F7-0F95-4E9B-9F50-F74EAA8C2105}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flute_lib", "src\flute_lib\flute_lib.vcproj", "{FCD7B10A-D566-4233-AFB1-2CEDEAAA064C}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "flute", "flute\flute.vcproj", "{D62E15CB-88C0-4821-9B67-3144825DFF9C}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + {EFA02B50-FACA-4736-8324-BAEEB9EED725}.0 = {B42905F7-0F95-4E9B-9F50-F74EAA8C2105} + {4D556DD8-A4A6-4C1A-99D7-614D498E86CA}.0 = {B42905F7-0F95-4E9B-9F50-F74EAA8C2105} + {4139BD27-57C0-434A-BA0E-E49AE4C50DDF}.0 = {B42905F7-0F95-4E9B-9F50-F74EAA8C2105} + {FCD7B10A-D566-4233-AFB1-2CEDEAAA064C}.0 = {B42905F7-0F95-4E9B-9F50-F74EAA8C2105} + {FCD7B10A-D566-4233-AFB1-2CEDEAAA064C}.1 = {B42905F7-0F95-4E9B-9F50-F74EAA8C2105} + {D62E15CB-88C0-4821-9B67-3144825DFF9C}.0 = {FCD7B10A-D566-4233-AFB1-2CEDEAAA064C} + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {B42905F7-0F95-4E9B-9F50-F74EAA8C2105}.Debug.ActiveCfg = Debug|Win32 + {B42905F7-0F95-4E9B-9F50-F74EAA8C2105}.Debug.Build.0 = Debug|Win32 + {B42905F7-0F95-4E9B-9F50-F74EAA8C2105}.Release.ActiveCfg = Release|Win32 + {B42905F7-0F95-4E9B-9F50-F74EAA8C2105}.Release.Build.0 = Release|Win32 + {EFA02B50-FACA-4736-8324-BAEEB9EED725}.Debug.ActiveCfg = Debug|Win32 + {EFA02B50-FACA-4736-8324-BAEEB9EED725}.Debug.Build.0 = Debug|Win32 + {EFA02B50-FACA-4736-8324-BAEEB9EED725}.Release.ActiveCfg = Release|Win32 + {EFA02B50-FACA-4736-8324-BAEEB9EED725}.Release.Build.0 = Release|Win32 + {4D556DD8-A4A6-4C1A-99D7-614D498E86CA}.Debug.ActiveCfg = Debug|Win32 + {4D556DD8-A4A6-4C1A-99D7-614D498E86CA}.Release.ActiveCfg = Release|Win32 + {4D556DD8-A4A6-4C1A-99D7-614D498E86CA}.Release.Build.0 = Release|Win32 + {4139BD27-57C0-434A-BA0E-E49AE4C50DDF}.Debug.ActiveCfg = Debug|Win32 + {4139BD27-57C0-434A-BA0E-E49AE4C50DDF}.Release.ActiveCfg = Release|Win32 + {4139BD27-57C0-434A-BA0E-E49AE4C50DDF}.Release.Build.0 = Release|Win32 + {B42905F7-0F95-4E9B-9F50-F74EAA8C2105}.Debug.ActiveCfg = Debug|Win32 + {B42905F7-0F95-4E9B-9F50-F74EAA8C2105}.Debug.Build.0 = Debug|Win32 + {B42905F7-0F95-4E9B-9F50-F74EAA8C2105}.Release.ActiveCfg = Release|Win32 + {B42905F7-0F95-4E9B-9F50-F74EAA8C2105}.Release.Build.0 = Release|Win32 + {FCD7B10A-D566-4233-AFB1-2CEDEAAA064C}.Debug.ActiveCfg = Debug|Win32 + {FCD7B10A-D566-4233-AFB1-2CEDEAAA064C}.Debug.Build.0 = Debug|Win32 + {FCD7B10A-D566-4233-AFB1-2CEDEAAA064C}.Release.ActiveCfg = Release|Win32 + {FCD7B10A-D566-4233-AFB1-2CEDEAAA064C}.Release.Build.0 = Release|Win32 + {D62E15CB-88C0-4821-9B67-3144825DFF9C}.Debug.ActiveCfg = Debug|Win32 + {D62E15CB-88C0-4821-9B67-3144825DFF9C}.Debug.Build.0 = Debug|Win32 + {D62E15CB-88C0-4821-9B67-3144825DFF9C}.Release.ActiveCfg = Release|Win32 + {D62E15CB-88C0-4821-9B67-3144825DFF9C}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/robcast/Makefile b/robcast/Makefile new file mode 100644 index 0000000..9e96c06 --- /dev/null +++ b/robcast/Makefile @@ -0,0 +1,107 @@ +# $Id: Makefile,v 1.20 2004/10/14 14:21:50 roca Exp $ +# +# Makefile +# + +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Makefile.common as appropriate +include ../Makefile.common + + +# libraries required +ifeq (${OS},linux) + # Linux version + # MCL library requires -lpthread + # add MPATROL support if required + # + BINDIR = ../bin/linux + LDPC_BINDIR = ../../ldpc/bin/linux + LIBRARIES = -lc -lm -lpthread ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +endif + +ifeq (${OS},solaris) + # Solaris version: requires -lsocket -lnsl and -L/usr/ucblib -lucb + # + BINDIR = ../bin/solaris + LDPC_BINDIR = ../../ldpc/bin/solaris + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lposix4 -lpthread ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +endif + +ifeq (${OS},freebsd) + # FreeBSD version + # MCL library requires -pthread + # + BINDIR = ../bin/freebsd + LDPC_BINDIR = ../../ldpc/bin/freebsd + LIBRARIES = -lm -pthread ${BINDIR}/libmclalc.a + LIBRARIES = -lm -pthread ${BINDIR}/libmclalc.a ${LDPC_BINDIR}/libldpc.a +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +CFLAGS = -O -g -DALC ${OSFLAGS} + +# cc version +# -fullwarn for IRIX c compiler +#CFLAGS = -O -fullwarn -DALC ${OSFLAGS} + +# add purify linker for memory debug (Solaris only). +# Purify 4.0 Solaris 2, Copyright (C) 1992-1996 Pure Software Inc. +# +#CCLINK_PURE = purify $(CC) +CCLINK_PURE = purify -cache-dir=/tmp $(CC) + + +# List of source and object test files +SRCFILES = robcast_client.c robcast_server.c +OFILES = ${SRCFILES:.c=.o} + + +###### Dependancies ###### + +all: ${BINDIR}/robcast_client ${BINDIR}/robcast_server + +${BINDIR}/robcast_client: robcast_client.o ${BINDIR}/libmclalc.a + @echo "** Compiling robcast_client with ALC support..." + ${CC} ${CFLAGS} robcast_client.o ${LIBRARIES} -o ${BINDIR}/robcast_client + #strip ${BINDIR}/robcast_client + +${BINDIR}/robcast_server: robcast_server.o ${BINDIR}/libmclalc.a + @echo "** Compiling robcast_server with ALC support..." + ${CC} ${CFLAGS} robcast_server.o ${LIBRARIES} -o ${BINDIR}/robcast_server + #strip ${BINDIR}/robcast_server + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in ${BINDIR}/robcast_client ${BINDIR}/robcast_server ${BINDIR}/robcast_server_repository.txt ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +robcast_client.o: robcast.h ../src/common/mcl_lib_api.h +robcast_client.o: ../src/common/mcl_types.h ../src/alc/mcl_lib_api_alc.h +robcast_server.o: robcast.h ../src/common/mcl_lib_api.h +robcast_server.o: ../src/common/mcl_types.h ../src/alc/mcl_lib_api_alc.h diff --git a/robcast/README b/robcast/README new file mode 100644 index 0000000..ef0bc34 --- /dev/null +++ b/robcast/README @@ -0,0 +1,64 @@ + $Id: README,v 1.1.1.1 2003/09/03 12:45:43 chneuman Exp $ + + ---------------------------------------- + The RobCast Application + README - Vincent Roca + ---------------------------------------- + + +Motivations +----------- + +The Rob"ust"Cast application is a demonstration which exhibits the major +assets of ALC/LCT in terms of robustness and source/receiver Independence. +More precisely the RobCast application is meant to TOLERATE ANY CLIENT AND +SERVER REBOOT, AT ANY TIME. + +A CLIENT reboot must not affect in any way the server, and the client must be +able to catch up the session after it is available again without any problem. + +A SERVER reboot must not lead the clients to fail, but the clients must +notice it and must only consider new messages sent after the server reboot. + +The current version is essentially a demo application, since no effective +data is effectively carried by RobCAST. It must be regarded as a framework +that enables the design of more elaborated robust client/server applications. + + +Internals +--------- + +These features are made possible by an intelligent use of the TSI (Transport +Session Identifier) of LCT, which along with the source address, uniquely +identifies any ALC/LCT session, and of the TOI (Transport Object Identifier) +which uniquely identifies any object sent in an ALC/LCT session. +Two ALC/LCT sessions are used: + * a control session, which is used to carry RobCast control + information, and + * a data session, where the application data is sent. +More precisely, whenever the RobCast server restarts, this latter allocates +a new TSI to be used on the data session, and sends this information to +RobCast clients on the control session. The server then sets this TSI on +its data session. +A client first receives the new TSI to be used by the server from its control +session, closes its data session to flush all pending MCL buffers, and +opens a new data session using this TSI. +Because each new TSI control message sent by the server must have a unique +identifier, after a server reboot, this latter must first retrieve the +old TOI identifier used on its previous incarnation, increment it and switch +to this new TOI before issuing the TSI control message. +Therefore a server must use a permanent repository where two informations +are stored: + * the next TSI to use on the data session, and + * the next TOI to use for the TSI control message. +These informations are kept in a file, "robcast_server_repository.txt", +along with the RobCast binaries. If this file does not exist, it is +automatically created. + + +Acknowledgments +--------------- + +The authors would like to thank Eric NICOLAS (nicolas00@wanadoo.fr) +for his contributions and discussion to the RobCast tool. + diff --git a/robcast/robcast.h b/robcast/robcast.h new file mode 100644 index 0000000..45c0a3b --- /dev/null +++ b/robcast/robcast.h @@ -0,0 +1,64 @@ +/* $Id: robcast.h,v 1.1.1.1 2003/09/03 12:45:43 chneuman Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#define S_IRWXU _S_IWRITE +#else +#include +#include +#include +#include /* for sleep */ +#endif /* OS_DEP */ + +#include /* for exit */ +#include "../src/common/mcl_lib_api.h" + + +/* + * print and exit + */ +#define EXIT(a) { printf a; fflush(stdout); exit(-1); } + +/* + * test, print and exit if error (i.e. if != 0) + */ +#define EXIT_ON_ERROR(err, a) { if (err) { EXIT(a) } } + + +#define BUFLEN 150 /* buffer size */ +#define SESSION_NB 2 /* two sessions: ctrl (0), data (1) */ +#define CTRL_IDX 0 /* index in tabs for ctrl session */ +#define DATA_IDX 1 /* index in tabs for data session */ + +#define CTRL_PORT 13200 +#define DATA_PORT 13250 +#define CTRL_ADDR "225.132.0.0" +#define DATA_ADDR "225.133.0.0" diff --git a/robcast/robcast_client.c b/robcast/robcast_client.c new file mode 100644 index 0000000..0f7a71e --- /dev/null +++ b/robcast/robcast_client.c @@ -0,0 +1,194 @@ +/* $Id: robcast_client.c,v 1.3 2004/11/29 17:07:29 chneuman Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * robcast_client.c + * Test MCL robustness in front of either client or server reboot. + * A server reboot triggers a TSI update, in order to distinguish + * the sessions before and after the reboot. + * A client reboot must not affect reception. + * The session follows an on-demand delivery mode in order to + * enable asynchronous client arrivals. + * Two MCL sessions are created: a control session (TSI=0) used by + * the server to announce communicate the new TSI to use, and a + * data session (using the new TSI) to convey data. + */ + +#include "robcast.h" + +#define VERBOSITY_CTRL 0 /* verbosity level for control session*/ +#define VERBOSITY_DATA 0 /* verbosity level for data session */ + + +int id[SESSION_NB]; /* MCL session identifiers */ +int port[SESSION_NB]; +unsigned long addr[SESSION_NB]; +int verbose[SESSION_NB]; +int cur_TSI = 0; /* current Transport Session Id to */ + /* use for data session */ + + +/* + * Create and setup a session (ctrl or data) + */ +void +setup_session (int index) +{ + int err; /* error return value */ + int unset = 0; + + if ((id[index] = mcl_open("r")) < 0) + EXIT(("client/setup_session: ERROR: mcl_open failed for session %d\n", index)) + if (verbose[index] > 0) { + err = mcl_ctl(id[index], MCL_OPT_VERBOSITY, (void*)&verbose[index], + sizeof(verbose[index])); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR: mcl_ctl VERBOSITY failed for session %d\n", index)) + } + /* don't use the virtual memory service here (small messages) */ + mcl_ctl(id[index], MCL_OPT_VIRTUAL_RX_MEMORY, (void*)&unset, + sizeof(unset)); + /* Select the appropriate multicast address and port */ + err = mcl_ctl(id[index], MCL_OPT_ADDR, (void*)&addr[index], sizeof(addr[index])); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR, MCL_OPT_ADDR failed for session %d\n", index)) + err = mcl_ctl(id[index], MCL_OPT_PORT, (void*)&port[index], sizeof(port[index])); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR, MCL_OPT_PORT failed for session %d\n", index)) + if (index == CTRL_IDX) { + int set = 1; + /* switch to immediate delivery mode */ + err = mcl_ctl(id[index], MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, (void*)&set, sizeof(set)); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR, MCL_OPT_IMMEDIATE_DELIVERY failed\n")) + } +} + + +/* + * MCL control session management. + * Receives new TSI announcements, and controls the data session + * accordingly. + */ +void +ctrl_mgmt (void) +{ + int new_TSI = 0; /* Transport Session Id just received. It can */ + /* be a reminder, or a new TSI... */ + int ret; + int err; /* error return value */ + fd_set readfs; + + FD_ZERO(&readfs); + FD_SET(id[CTRL_IDX], &readfs); + /* don't wait here */ + ret = mcl_select(id[CTRL_IDX]+1, &readfs, NULL, NULL, NULL); + if (ret < 0) + EXIT(("client/ctrl_mgmt: ERROR, mcl_select failed")) + if (ret == 0) { + /* nothing received, so return */ + /*printf("client/ctrl_mgmt: no new TSI received yet\n");*/ + return; + } + /* something available... */ + if (ret != 1) + EXIT(("client/ctrl_mgmt: ERROR, expected ret == 1, got %d", ret)) + if ((ret = mcl_recv(id[CTRL_IDX], &new_TSI, sizeof(new_TSI))) < 0) + EXIT(("client/ctrl_mgmt: ERROR, control session closed")) + if (ret == 0) + EXIT(("client/ctrl_mgmt: ERROR, read on control session returns 0 whereas mcl_select() says there's data!")) + new_TSI = ntohl(new_TSI); + if (new_TSI == cur_TSI) { + /* nothing to do... this is just a reminder */ + printf("robcast_client: recvd a reminder for TSI=%d\n", new_TSI); + return; + } + /* + * switch to new TSI. + * It requires to close the close the current data + * session (to flush buffers), reopen a new session + * and specifying the new TSI to use. + */ + printf("robcast_client: switch to new TSI=%d...\n", new_TSI); + mcl_close(id[DATA_IDX]); + setup_session(DATA_IDX); + err = mcl_ctl(id[DATA_IDX], MCL_OPT_DEMUX_LABEL, (void*)&new_TSI, sizeof(new_TSI)); + EXIT_ON_ERROR(err, ( + "client/setup_session: ERROR, MCL_OPT_DEMUX_LABEL failed for data session\n")) +} + + +int +main (int argc, + char *argv[]) +{ + char buf[BUFLEN]; + struct timeval timeout; + int ret; + fd_set readfs; + + port[CTRL_IDX] = CTRL_PORT; /* in host format (required by MCL) */ + port[DATA_IDX] = DATA_PORT; + addr[CTRL_IDX] = ntohl(inet_addr(CTRL_ADDR)); /* in host format */ + /* (required by MCL) */ + addr[DATA_IDX] = ntohl(inet_addr(DATA_ADDR)); + verbose[CTRL_IDX] = VERBOSITY_CTRL; + verbose[DATA_IDX] = VERBOSITY_DATA; + + printf("robcast_client: create and init two sessions...\n"); + setup_session(CTRL_IDX); + setup_session(DATA_IDX); + printf("robcast_client: wait for data now til we're stopped...\n"); + + /* + * start data reception now. + */ + while (1) { + FD_ZERO(&readfs); + FD_SET(id[DATA_IDX], &readfs); + timeout.tv_sec = 0; /* 0.1 second timeout */ + timeout.tv_usec = 100000; + ret = mcl_select(id[DATA_IDX]+1, &readfs, NULL, NULL, &timeout); + if (ret < 0) { + EXIT(("client/main: ERROR, mcl_select failed")) + } else if (ret == 0) { + /* nothing received, check the control session now... */ + /*printf("client/ctrl_mgmt: no new data received yet\n");*/ + ctrl_mgmt(); + } else if (ret != 1) { + EXIT(("client/main: ERROR, expected ret == 1, got %d", ret)) + } else { + if ((ret = mcl_recv(id[DATA_IDX], buf, BUFLEN)) < 0) + EXIT(("client/main: data session closed\n")) + printf("new message received from robcast_server:\n\t%s\n", buf); +#if 0 + /* + * depending on the appli, you can also stop + * the client once he received a data message... + */ + printf("\n\t... robcast_client ok\n"); + return 0; +#endif + } + } + return -1; +} + diff --git a/robcast/robcast_client.vcproj b/robcast/robcast_client.vcproj new file mode 100644 index 0000000..35155f0 --- /dev/null +++ b/robcast/robcast_client.vcproj @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/robcast/robcast_server.c b/robcast/robcast_server.c new file mode 100644 index 0000000..2ba5144 --- /dev/null +++ b/robcast/robcast_server.c @@ -0,0 +1,224 @@ +/* $Id: robcast_server.c,v 1.2 2004/11/29 17:07:29 chneuman Exp $ */ +/* + * Copyright (c) 1999-2002 INRIA - Universite Paris 6 - All rights reserved + * (main authors: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * robcast_server.c + * Test MCL robustness in front of either client or server reboot. + * A server reboot triggers a TSI update, in order to distinguish + * the sessions before and after the reboot. + * A client reboot must not affect reception. + * The session follows an on-demand delivery mode in order to + * enable asynchronous client arrivals. + * Two MCL sessions are created: a control session (TSI=0) used by + * the server to announce communicate the new TSI to use, and a + * data session (using the new TSI) to convey data. + */ + +#include "robcast.h" + +#define VERBOSITY_CTRL 0 /* verbosity level for control session*/ +#define VERBOSITY_DATA 0 /* verbosity level for data session */ + + +int id[SESSION_NB]; /* MCL session identifiers */ +int port[SESSION_NB]; +unsigned long addr[SESSION_NB]; +int verbose[SESSION_NB]; +int cur_TSI = -1; /* current Transport Session Id to */ + /* use for data session */ +int cur_TOI = -1; /* current Transport Object Id to */ + /* use to carry the TSI announcement */ + + +/* + * Create and setup a session (ctrl or data) + */ +void +setup_session (int index) +{ + int err; /* error return value */ + int delivery_mode = DEL_MODE_ON_DEMAND; + int unset = 0; + + if ((id[index] = mcl_open("w")) < 0) + EXIT(("server/setup_session: ERROR: mcl_open failed for session %d\n", index)) + if (verbose[index] > 0) { + err = mcl_ctl(id[index], MCL_OPT_VERBOSITY, (void*)&verbose[index], + sizeof(verbose[index])); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR: mcl_ctl VERBOSITY failed for session %d\n", index)) + } + /* don't use the virtual memory service here (small messages) */ + mcl_ctl(id[index], MCL_OPT_VIRTUAL_TX_MEMORY, (void*)&unset, + sizeof(unset)); + /* Select the appropriate multicast address and port */ + err = mcl_ctl(id[index], MCL_OPT_ADDR, (void*)&addr[index], sizeof(addr[index])); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR, MCL_OPT_ADDR failed for session %d\n", index)) + err = mcl_ctl(id[index], MCL_OPT_PORT, (void*)&port[index], sizeof(port[index])); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR, MCL_OPT_PORT failed for session %d\n", index)) + /* Switch to "on demand" delivery mode */ + err = mcl_ctl(id[index], MCL_OPT_DELIVERY_MODE, (void*)&delivery_mode, + sizeof(delivery_mode)); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR, MCL_OPT_DELIVERY_MODE failed\n")) + if (index == CTRL_IDX) { + float fec = 1.0; /* n/k = 1.0 means no FEC */ + /* no need for FEC here */ + err = mcl_ctl(id[index], MCL_OPT_FEC_RATIO, (void*)&fec, sizeof(fec)); + EXIT_ON_ERROR(err, ( + "server/setup_session: ERROR, MCL_OPT_FEC_RATIO failed\n")) + + } +} + + +/* + * MCL control session management. + * Retrieves the new TSI to use for the data session (i.e. TSI of the + * previous data session + 1) + * and the new TOI to use for the control session (i.e. TSI of the + * previous control session + 1) + * which are both stored on a permanent location (i.e. a file), then + * send the TSI periodically in the control session (in case a client + * is restarted) in the object of identifier TOI. + */ +void +ctrl_mgmt (void) +{ + int buf[1]; /* buffer sent on ctrl session which */ + /* contains TSI in network format */ + char tsi_file_name[] = "./robcast_server_repository.txt"; + /* name of permanent TSI depository */ + int fd_tsi = -1; /* fd to file containing the TSI value*/ + FILE *FILE_tsi = NULL; /* ptr to file containing TSI value */ + int ret; + int err; /* error return value */ + + /* + * First, retrieve the TSI to use. If the variable cur_TSI is not set, + * (e.g. after a reboot), then retrieve it from disk file, if any, + * or create this file. + */ + if (cur_TSI == -1) { + /* server has been restarted, so search the TSI from disk */ + if ((fd_tsi = open(tsi_file_name, O_RDWR)) < 0) { + if (errno != ENOENT) { + perror("server/ctrl_mgmt: open failed 1"); + EXIT(("server/ctrl_mgmt: ERROR while opening file %s\n", tsi_file_name)) + } + /* does not exist */ + cur_TSI = 1; /* reset TSI (must be >= 0) */ + cur_TOI = 1; /* reset TSI (must be >= 1) */ + printf("\t\trobcast_server: no TSI/TOI repository, create it\n"); + + if ((fd_tsi = open( tsi_file_name, O_WRONLY | O_CREAT, S_IRWXU)) < 0) { + perror("server/ctrl_mgmt: open failed 2"); + EXIT(("server/ctrl_mgmt: ERROR while creating file %s\n", tsi_file_name)) + } + if ((FILE_tsi = fdopen(fd_tsi, "w")) == NULL) { + perror("server/ctrl_mgmt: fdopen failed"); + EXIT(("server/ctrl_mgmt: ERROR, fdopen failed\n")) + } + } else { + /* read the value, increment it, and save it */ + if ((FILE_tsi = fdopen(fd_tsi, "r+")) == NULL) { + perror("server/ctrl_mgmt: fdopen failed"); + EXIT(("server/ctrl_mgmt: ERROR, fdopen failed\n")) + } + if ((ret = fscanf(FILE_tsi, "next_TSI=%d next_TOI=%d", &cur_TSI, &cur_TOI)) != 2) { + perror("server/ctrl_mgmt: fscanf failed"); + EXIT(("server/ctrl_mgmt: ERROR, fscanf failed\n")) + } + rewind(FILE_tsi); + printf("\trobcast_server: found the TSI/TOI repository\n"); + } + /* store the next TSI and TOI to use, flush it and close */ + fprintf(FILE_tsi, "next_TSI=%d next_TOI=%d", cur_TSI+1, cur_TOI+1); + fflush(FILE_tsi); + if (fclose(FILE_tsi) != 0) { + perror("server/ctrl_mgmt: fclose failed"); + EXIT(("server/ctrl_mgmt: ERROR, fclose failed\n")) + } + /* fclose() implicitely issues a close() too */ + /* set the new TSI on the data session */ + printf("\trobcast_server: switch to new TSI=%d\n", cur_TSI); + err = mcl_ctl(id[DATA_IDX], MCL_OPT_DEMUX_LABEL, (void*)&cur_TSI, sizeof(cur_TSI)); + EXIT_ON_ERROR(err, ( + "server/ctrl_mgmt: ERROR, MCL_OPT_DEMUX_LABEL failed for data session\n")) + /* set the new TOI for the control session */ + printf("\trobcast_server: switch to new TOI=%d\n", cur_TOI); + err = mcl_ctl(id[CTRL_IDX], MCL_OPT_SET_NEXT_TOI, (void*)&cur_TOI, sizeof(cur_TOI)); + EXIT_ON_ERROR(err, ( + "server/ctrl_mgmt: ERROR, MCL_OPT_SET_NEXT_TOI failed for control session\n")) + } + /* + * Secondly, send the new TSI to clients... + */ + buf[0] = htonl(cur_TSI); + if ((ret = mcl_send(id[CTRL_IDX], &buf, sizeof(buf))) < 0) + EXIT(("server/ctrl_mgmt: ERROR, control session closed")) + /*printf("\t\trobcast_server: TSI msg sent on ctrl session\n");*/ +} + + +int +main (int argc, + char *argv[]) +{ + char buf[BUFLEN]; + int ret; + + port[CTRL_IDX] = CTRL_PORT; /* in host format (required by MCL) */ + port[DATA_IDX] = DATA_PORT; + addr[CTRL_IDX] = ntohl(inet_addr(CTRL_ADDR)); /* in host format */ + /* (required by MCL) */ + addr[DATA_IDX] = ntohl(inet_addr(DATA_ADDR)); + verbose[CTRL_IDX] = VERBOSITY_CTRL; + verbose[DATA_IDX] = VERBOSITY_DATA; + + printf("\trobcast_server: create and init two sessions...\n"); + setup_session(CTRL_IDX); + setup_session(DATA_IDX); + + /* + * start data transmission now. + */ + ctrl_mgmt(); + printf("\trobcast_server: send data and wait til we're stopped...\n"); + sprintf(buf, "Hi all, this is an HELLO message sent on data session/TSI=%d", cur_TSI); + if ((ret = mcl_send(id[DATA_IDX], buf, strlen(buf)+1)) < 0) + EXIT(("server/main: data session closed\n")) + /* + * and now loop forever while MCL-ALC sends data in on-demand mode... + */ + while (1) + { +#ifdef WIN32 + Sleep(1); +#else + sleep(1); +#endif + } + return 0; +} + diff --git a/robcast/robcast_server.vcproj b/robcast/robcast_server.vcproj new file mode 100644 index 0000000..4b026f6 --- /dev/null +++ b/robcast/robcast_server.vcproj @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/alc/Makefile b/src/alc/Makefile new file mode 100644 index 0000000..ddd3e97 --- /dev/null +++ b/src/alc/Makefile @@ -0,0 +1,780 @@ +# $Id: Makefile,v 1.64 2005/05/24 15:43:21 roca Exp $ +# +# Makefile +# + +###### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Makefile.common as appropriate +include ../../Makefile.common + + +ifeq (${OS},linux) + # Linux version + BINDIR = ../../bin/linux + LDPC_BINDIR = ../../../ldpc/bin/linux + LIBRARIES = -lc -lm -lpthread + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},solaris) + # Solaris version + BINDIR = ../../bin/solaris + LDPC_BINDIR = ../../../ldpc/bin/solaris + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lpthread + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},freebsd) + # FreeBSD version + BINDIR = ../../bin/freebsd + LDPC_BINDIR = ../../../ldpc/bin/freebsd + LIBRARIES = -lm -pthread + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},aix) + # AIX version + BINDIR = ../../bin/aix + LDPC_BINDIR = ../../../ldpc/bin/aix + LIBRARIES = -lm -pthread -lc + # TBC + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},hp-ux) + # HP-UX version + BINDIR = ../../bin/hp-ux + LDPC_BINDIR = ../../../ldpc/bin/hp-ux + LIBRARIES = -lc -lm -pthread + # TBC + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},irix) + # IRIX version + BINDIR = ../../bin/irix + LDPC_BINDIR = ../../../ldpc/bin/irix + LIBRARIES = -lc -lm -pthread + # TBC + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + + +###### Other Variables ###### + +# Common source files are here... +COMMON_DIR = ../common/ + +# List of source, object and include files +# +SRCFILES = ${COMMON_DIR}/mcl_addr.cpp ${COMMON_DIR}/mcl_socket_lib.cpp ${COMMON_DIR}/mcl_blocking_struct.cpp ${COMMON_DIR}/mcl_debug.cpp ${COMMON_DIR}/mcl_osdep.cpp ${COMMON_DIR}/rse_fec.cpp ${COMMON_DIR}/mcl_itime.cpp ${COMMON_DIR}/mcl_periodic_timer.cpp ${COMMON_DIR}/mcl_file_io.cpp mcl_cb.cpp mcl_periodic_proc.cpp mcl_vtmem.cpp mcl_vrmem.cpp mcl_rx_storage.cpp mcl_layer.cpp mcl_socket.cpp mcl_lct_hdr.cpp mcl_alc_hdr.cpp mcl_tx_tab.cpp mcl_rlc.cpp mcl_flid_sl.cpp mcl.cpp mcl_lib.cpp mcl_tx_prof.cpp mcl_sched.cpp mcl_tx.cpp mcl_rx.cpp mcl_rx_window.cpp mcl_sig.cpp mcl_network.cpp mcl_du.cpp mcl_adu.cpp mcl_stats.cpp mcl_fec.cpp mcl_fsm.cpp mcl_flute.cpp mcl_meta_object.cpp mcl_meta_object_layer.cpp +OFILES = ${SRCFILES:.cpp=.o} + + +# General purpose local FLAGS. +# WARNING: with gcc/g++, never use -O3 optimisation (compiler bugs) +# +CFLAGS = -DALC ${OSFLAGS} ${LARGEFILE_FLAGS} -DDEBUG -g # debug version +#CFLAGS = -DALC ${OSFLAGS} ${LARGEFILE_FLAGS} -O -g # optimized +#CFLAGS = -DALC ${OSFLAGS} ${LARGEFILE_FLAGS} -O -g -pg # optimized with profiling + +LDFLAGS = + + +###### Dependancies ###### +# by default, create the MCL lib +all: lib + +# Rule for C++ .cpp extension +.cpp.o: + $(CC) -c $(CFLAGS) -o $*.o $*.cpp + +lib : ${OFILES} + @echo "** Now create the MCL-ALC library..." + # Choose between the following two versions, according to + # the FEC in use... + # + # RSE_FEC version + ${AR} -rcsv ${BINDIR}/libmclalc.a ${OFILES} + # + # LDPC FEC version: add the libldpc.a library + #${AR} -rcsv ${BINDIR}/libmclalc.a ${OFILES} ${LDPC_BINDIR}/libldpc.a + ${RANLIB} ${BINDIR}/libmclalc.a + @echo "done" + +clean : + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in ${BINDIR}/libmclalc*.a ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +../common//mcl_addr.o: ../alc/mcl_includes.h ../common/mcl_types.h +../common//mcl_addr.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_addr.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_addr.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +../common//mcl_addr.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_addr.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +../common//mcl_addr.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_addr.o: ../common/mcl_blocking_struct.h +../common//mcl_addr.o: ../common/mcl_periodic_timer.h ../common/mcl_file_io.h +../common//mcl_addr.o: mcl.h mcl_error.h ../common/rse_fec.h +../common//mcl_addr.o: ../../../ldpc/src/ldpc_fec.h +../common//mcl_addr.o: ../../../ldpc/src/ldpc_matrix_sparse.h +../common//mcl_addr.o: ../../../ldpc/src/tools.h +../common//mcl_addr.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h +../common//mcl_addr.o: mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +../common//mcl_addr.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h +../common//mcl_addr.o: mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +../common//mcl_addr.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +../common//mcl_addr.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +../common//mcl_addr.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +../common//mcl_socket_lib.o: ../alc/mcl_includes.h ../common/mcl_types.h +../common//mcl_socket_lib.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_socket_lib.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_socket_lib.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +../common//mcl_socket_lib.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_socket_lib.o: ../common/ssm_for_linux.h +../common//mcl_socket_lib.o: ../common/mcl_socket_lib.h ../common/mcl_debug.h +../common//mcl_socket_lib.o: ../common/mcl_itime.h +../common//mcl_socket_lib.o: ../common/mcl_blocking_struct.h +../common//mcl_socket_lib.o: ../common/mcl_periodic_timer.h +../common//mcl_socket_lib.o: ../common/mcl_file_io.h mcl.h mcl_error.h +../common//mcl_socket_lib.o: ../common/rse_fec.h ../../../ldpc/src/ldpc_fec.h +../common//mcl_socket_lib.o: ../../../ldpc/src/ldpc_matrix_sparse.h +../common//mcl_socket_lib.o: ../../../ldpc/src/tools.h +../common//mcl_socket_lib.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h +../common//mcl_socket_lib.o: mcl_data.h mcl_vrmem.h mcl_rx_storage.h +../common//mcl_socket_lib.o: mcl_tx_tab.h mcl_rlc.h mcl_flid_sl.h +../common//mcl_socket_lib.o: mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h +../common//mcl_socket_lib.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +../common//mcl_socket_lib.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h +../common//mcl_socket_lib.o: mcl_cb.h mcl_fec.h mcl_meta_object.h +../common//mcl_socket_lib.o: mcl_meta_object_layer.h +../common//mcl_blocking_struct.o: ../alc/mcl_includes.h ../common/mcl_types.h +../common//mcl_blocking_struct.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_blocking_struct.o: ../common/mcl_defines.h +../common//mcl_blocking_struct.o: ../common/mcl_lib_api.h +../common//mcl_blocking_struct.o: ../common/mcl_types.h +../common//mcl_blocking_struct.o: ../alc/mcl_lib_api_alc.h +../common//mcl_blocking_struct.o: ../common/mcl_version.h +../common//mcl_blocking_struct.o: ../common/mcl_addr.h +../common//mcl_blocking_struct.o: ../common/ssm_for_linux.h +../common//mcl_blocking_struct.o: ../common/mcl_socket_lib.h +../common//mcl_blocking_struct.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_blocking_struct.o: ../common/mcl_blocking_struct.h +../common//mcl_blocking_struct.o: ../common/mcl_periodic_timer.h +../common//mcl_blocking_struct.o: ../common/mcl_file_io.h mcl.h mcl_error.h +../common//mcl_blocking_struct.o: ../common/rse_fec.h +../common//mcl_blocking_struct.o: ../../../ldpc/src/ldpc_fec.h +../common//mcl_blocking_struct.o: ../../../ldpc/src/ldpc_matrix_sparse.h +../common//mcl_blocking_struct.o: ../../../ldpc/src/tools.h +../common//mcl_blocking_struct.o: ../../../ldpc/src/ldpc_create_pchk.h +../common//mcl_blocking_struct.o: mcl_lib.h mcl_data.h mcl_vrmem.h +../common//mcl_blocking_struct.o: mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +../common//mcl_blocking_struct.o: mcl_flid_sl.h mcl_socket.h +../common//mcl_blocking_struct.o: mcl_periodic_proc.h mcl_lct_hdr.h +../common//mcl_blocking_struct.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h +../common//mcl_blocking_struct.o: mcl_proto.h mcl_rx.h mcl_rx_window.h +../common//mcl_blocking_struct.o: mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +../common//mcl_blocking_struct.o: mcl_meta_object.h mcl_meta_object_layer.h +../common//mcl_debug.o: ../alc/mcl_includes.h ../common/mcl_types.h +../common//mcl_debug.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_debug.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_debug.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +../common//mcl_debug.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_debug.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +../common//mcl_debug.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_debug.o: ../common/mcl_blocking_struct.h +../common//mcl_debug.o: ../common/mcl_periodic_timer.h +../common//mcl_debug.o: ../common/mcl_file_io.h mcl.h mcl_error.h +../common//mcl_debug.o: ../common/rse_fec.h ../../../ldpc/src/ldpc_fec.h +../common//mcl_debug.o: ../../../ldpc/src/ldpc_matrix_sparse.h +../common//mcl_debug.o: ../../../ldpc/src/tools.h +../common//mcl_debug.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h +../common//mcl_debug.o: mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +../common//mcl_debug.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h +../common//mcl_debug.o: mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +../common//mcl_debug.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +../common//mcl_debug.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +../common//mcl_debug.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +../common//mcl_osdep.o: ../alc/mcl_includes.h ../common/mcl_types.h +../common//mcl_osdep.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_osdep.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_osdep.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +../common//mcl_osdep.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_osdep.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +../common//mcl_osdep.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_osdep.o: ../common/mcl_blocking_struct.h +../common//mcl_osdep.o: ../common/mcl_periodic_timer.h +../common//mcl_osdep.o: ../common/mcl_file_io.h mcl.h mcl_error.h +../common//mcl_osdep.o: ../common/rse_fec.h ../../../ldpc/src/ldpc_fec.h +../common//mcl_osdep.o: ../../../ldpc/src/ldpc_matrix_sparse.h +../common//mcl_osdep.o: ../../../ldpc/src/tools.h +../common//mcl_osdep.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h +../common//mcl_osdep.o: mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +../common//mcl_osdep.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h +../common//mcl_osdep.o: mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +../common//mcl_osdep.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +../common//mcl_osdep.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +../common//mcl_osdep.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +../common//rse_fec.o: ../common/mcl_debug.h +../common//mcl_itime.o: ../alc/mcl_includes.h ../common/mcl_types.h +../common//mcl_itime.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_itime.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_itime.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +../common//mcl_itime.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_itime.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +../common//mcl_itime.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_itime.o: ../common/mcl_blocking_struct.h +../common//mcl_itime.o: ../common/mcl_periodic_timer.h +../common//mcl_itime.o: ../common/mcl_file_io.h mcl.h mcl_error.h +../common//mcl_itime.o: ../common/rse_fec.h ../../../ldpc/src/ldpc_fec.h +../common//mcl_itime.o: ../../../ldpc/src/ldpc_matrix_sparse.h +../common//mcl_itime.o: ../../../ldpc/src/tools.h +../common//mcl_itime.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h +../common//mcl_itime.o: mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +../common//mcl_itime.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h +../common//mcl_itime.o: mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +../common//mcl_itime.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +../common//mcl_itime.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +../common//mcl_itime.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +../common//mcl_periodic_timer.o: ../alc/mcl_includes.h ../common/mcl_types.h +../common//mcl_periodic_timer.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_periodic_timer.o: ../common/mcl_defines.h +../common//mcl_periodic_timer.o: ../common/mcl_lib_api.h +../common//mcl_periodic_timer.o: ../common/mcl_types.h +../common//mcl_periodic_timer.o: ../alc/mcl_lib_api_alc.h +../common//mcl_periodic_timer.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_periodic_timer.o: ../common/ssm_for_linux.h +../common//mcl_periodic_timer.o: ../common/mcl_socket_lib.h +../common//mcl_periodic_timer.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_periodic_timer.o: ../common/mcl_blocking_struct.h +../common//mcl_periodic_timer.o: ../common/mcl_periodic_timer.h +../common//mcl_periodic_timer.o: ../common/mcl_file_io.h mcl.h mcl_error.h +../common//mcl_periodic_timer.o: ../common/rse_fec.h +../common//mcl_periodic_timer.o: ../../../ldpc/src/ldpc_fec.h +../common//mcl_periodic_timer.o: ../../../ldpc/src/ldpc_matrix_sparse.h +../common//mcl_periodic_timer.o: ../../../ldpc/src/tools.h +../common//mcl_periodic_timer.o: ../../../ldpc/src/ldpc_create_pchk.h +../common//mcl_periodic_timer.o: mcl_lib.h mcl_data.h mcl_vrmem.h +../common//mcl_periodic_timer.o: mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +../common//mcl_periodic_timer.o: mcl_flid_sl.h mcl_socket.h +../common//mcl_periodic_timer.o: mcl_periodic_proc.h mcl_lct_hdr.h +../common//mcl_periodic_timer.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h +../common//mcl_periodic_timer.o: mcl_proto.h mcl_rx.h mcl_rx_window.h +../common//mcl_periodic_timer.o: mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +../common//mcl_periodic_timer.o: mcl_meta_object.h mcl_meta_object_layer.h +../common//mcl_file_io.o: ../alc/mcl_includes.h ../common/mcl_types.h +../common//mcl_file_io.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_file_io.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_file_io.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +../common//mcl_file_io.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_file_io.o: ../common/ssm_for_linux.h +../common//mcl_file_io.o: ../common/mcl_socket_lib.h ../common/mcl_debug.h +../common//mcl_file_io.o: ../common/mcl_itime.h +../common//mcl_file_io.o: ../common/mcl_blocking_struct.h +../common//mcl_file_io.o: ../common/mcl_periodic_timer.h +../common//mcl_file_io.o: ../common/mcl_file_io.h mcl.h mcl_error.h +../common//mcl_file_io.o: ../common/rse_fec.h ../../../ldpc/src/ldpc_fec.h +../common//mcl_file_io.o: ../../../ldpc/src/ldpc_matrix_sparse.h +../common//mcl_file_io.o: ../../../ldpc/src/tools.h +../common//mcl_file_io.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h +../common//mcl_file_io.o: mcl_data.h mcl_vrmem.h mcl_rx_storage.h +../common//mcl_file_io.o: mcl_tx_tab.h mcl_rlc.h mcl_flid_sl.h mcl_socket.h +../common//mcl_file_io.o: mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +../common//mcl_file_io.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +../common//mcl_file_io.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +../common//mcl_file_io.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +mcl_cb.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_cb.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_cb.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_cb.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_cb.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_cb.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_cb.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_cb.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_cb.o: ../../../ldpc/src/ldpc_fec.h ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_cb.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_cb.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_cb.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_cb.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_cb.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_cb.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_periodic_proc.o: mcl_includes.h ../common/mcl_types.h +mcl_periodic_proc.o: ../common/mcl_osdep.h mcl_profile.h +mcl_periodic_proc.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_periodic_proc.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_periodic_proc.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_periodic_proc.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_periodic_proc.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_periodic_proc.o: ../common/mcl_blocking_struct.h +mcl_periodic_proc.o: ../common/mcl_periodic_timer.h ../common/mcl_file_io.h +mcl_periodic_proc.o: mcl.h mcl_error.h ../common/rse_fec.h +mcl_periodic_proc.o: ../../../ldpc/src/ldpc_fec.h +mcl_periodic_proc.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_periodic_proc.o: ../../../ldpc/src/tools.h +mcl_periodic_proc.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h +mcl_periodic_proc.o: mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_periodic_proc.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_periodic_proc.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h +mcl_periodic_proc.o: mcl_proto.h mcl_rx.h mcl_rx_window.h mcl_flute.h +mcl_periodic_proc.o: mcl_tx.h mcl_cb.h mcl_fec.h mcl_meta_object.h +mcl_periodic_proc.o: mcl_meta_object_layer.h +mcl_vtmem.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_vtmem.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_vtmem.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_vtmem.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_vtmem.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_vtmem.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_vtmem.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_vtmem.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_vtmem.o: ../../../ldpc/src/ldpc_fec.h +mcl_vtmem.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_vtmem.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_vtmem.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +mcl_vtmem.o: mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h +mcl_vtmem.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +mcl_vtmem.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_vtmem.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_vrmem.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_vrmem.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_vrmem.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_vrmem.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_vrmem.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_vrmem.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_vrmem.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_vrmem.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_vrmem.o: ../../../ldpc/src/ldpc_fec.h +mcl_vrmem.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_vrmem.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_vrmem.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +mcl_vrmem.o: mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h +mcl_vrmem.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +mcl_vrmem.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_vrmem.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_rx_storage.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_rx_storage.o: mcl_profile.h ../common/mcl_defines.h +mcl_rx_storage.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_rx_storage.o: ../alc/mcl_lib_api_alc.h ../common/mcl_version.h +mcl_rx_storage.o: ../common/mcl_addr.h ../common/ssm_for_linux.h +mcl_rx_storage.o: ../common/mcl_socket_lib.h ../common/mcl_debug.h +mcl_rx_storage.o: ../common/mcl_itime.h ../common/mcl_blocking_struct.h +mcl_rx_storage.o: ../common/mcl_periodic_timer.h ../common/mcl_file_io.h +mcl_rx_storage.o: mcl.h mcl_error.h ../common/rse_fec.h +mcl_rx_storage.o: ../../../ldpc/src/ldpc_fec.h +mcl_rx_storage.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_rx_storage.o: ../../../ldpc/src/tools.h +mcl_rx_storage.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_rx_storage.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +mcl_rx_storage.o: mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_rx_storage.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h +mcl_rx_storage.o: mcl_proto.h mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h +mcl_rx_storage.o: mcl_cb.h mcl_fec.h mcl_meta_object.h +mcl_rx_storage.o: mcl_meta_object_layer.h +mcl_layer.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_layer.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_layer.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_layer.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_layer.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_layer.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_layer.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_layer.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_layer.o: ../../../ldpc/src/ldpc_fec.h +mcl_layer.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_layer.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_layer.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +mcl_layer.o: mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h +mcl_layer.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +mcl_layer.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_layer.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_socket.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_socket.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_socket.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_socket.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_socket.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_socket.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_socket.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_socket.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_socket.o: ../../../ldpc/src/ldpc_fec.h +mcl_socket.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_socket.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_socket.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_socket.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_socket.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_socket.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +mcl_socket.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +mcl_lct_hdr.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_lct_hdr.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_lct_hdr.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_lct_hdr.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_lct_hdr.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_lct_hdr.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_lct_hdr.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_lct_hdr.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_lct_hdr.o: ../../../ldpc/src/ldpc_fec.h +mcl_lct_hdr.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_lct_hdr.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_lct_hdr.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_lct_hdr.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_lct_hdr.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_lct_hdr.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +mcl_lct_hdr.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +mcl_alc_hdr.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_alc_hdr.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_alc_hdr.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_alc_hdr.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_alc_hdr.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_alc_hdr.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_alc_hdr.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_alc_hdr.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_alc_hdr.o: ../../../ldpc/src/ldpc_fec.h +mcl_alc_hdr.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_alc_hdr.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_alc_hdr.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_alc_hdr.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_alc_hdr.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_alc_hdr.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +mcl_alc_hdr.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +mcl_tx_tab.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_tx_tab.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_tx_tab.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_tx_tab.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_tx_tab.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_tx_tab.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_tx_tab.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_tx_tab.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_tx_tab.o: ../../../ldpc/src/ldpc_fec.h +mcl_tx_tab.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_tx_tab.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_tx_tab.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_tx_tab.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_tx_tab.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_tx_tab.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +mcl_tx_tab.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +mcl_rlc.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_rlc.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_rlc.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_rlc.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_rlc.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_rlc.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_rlc.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_rlc.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_rlc.o: ../../../ldpc/src/ldpc_fec.h +mcl_rlc.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_rlc.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_rlc.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h mcl_flid_sl.h +mcl_rlc.o: mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +mcl_rlc.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h mcl_rx_window.h +mcl_rlc.o: mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h mcl_meta_object.h +mcl_rlc.o: mcl_meta_object_layer.h +mcl_flid_sl.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_flid_sl.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_flid_sl.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_flid_sl.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_flid_sl.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_flid_sl.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_flid_sl.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_flid_sl.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_flid_sl.o: ../../../ldpc/src/ldpc_fec.h +mcl_flid_sl.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_flid_sl.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_flid_sl.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_flid_sl.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_flid_sl.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_flid_sl.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +mcl_flid_sl.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +mcl.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h ../common/mcl_version.h +mcl.o: ../common/mcl_addr.h ../common/ssm_for_linux.h +mcl.o: ../common/mcl_socket_lib.h ../common/mcl_debug.h ../common/mcl_itime.h +mcl.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl.o: ../../../ldpc/src/ldpc_fec.h ../../../ldpc/src/ldpc_matrix_sparse.h +mcl.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h +mcl.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +mcl.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_lib.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_lib.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_lib.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_lib.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_lib.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_lib.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_lib.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_lib.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_lib.o: ../../../ldpc/src/ldpc_fec.h +mcl_lib.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_lib.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_lib.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h mcl_flid_sl.h +mcl_lib.o: mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +mcl_lib.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h mcl_rx_window.h +mcl_lib.o: mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h mcl_meta_object.h +mcl_lib.o: mcl_meta_object_layer.h +mcl_tx_prof.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_tx_prof.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_tx_prof.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_tx_prof.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_tx_prof.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_tx_prof.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_tx_prof.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_tx_prof.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_tx_prof.o: ../../../ldpc/src/ldpc_fec.h +mcl_tx_prof.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_tx_prof.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_tx_prof.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_tx_prof.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_tx_prof.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_tx_prof.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +mcl_tx_prof.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +mcl_sched.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_sched.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_sched.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_sched.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_sched.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_sched.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_sched.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_sched.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_sched.o: ../../../ldpc/src/ldpc_fec.h +mcl_sched.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_sched.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_sched.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +mcl_sched.o: mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h +mcl_sched.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +mcl_sched.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_sched.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_tx.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_tx.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_tx.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_tx.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_tx.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_tx.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_tx.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_tx.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_tx.o: ../../../ldpc/src/ldpc_fec.h ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_tx.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_tx.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_tx.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_tx.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_tx.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_tx.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_rx.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_rx.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_rx.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_rx.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_rx.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_rx.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_rx.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_rx.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_rx.o: ../../../ldpc/src/ldpc_fec.h ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_rx.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_rx.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_rx.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_rx.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_rx.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_rx.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_rx_window.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_rx_window.o: mcl_profile.h ../common/mcl_defines.h +mcl_rx_window.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_rx_window.o: ../alc/mcl_lib_api_alc.h ../common/mcl_version.h +mcl_rx_window.o: ../common/mcl_addr.h ../common/ssm_for_linux.h +mcl_rx_window.o: ../common/mcl_socket_lib.h ../common/mcl_debug.h +mcl_rx_window.o: ../common/mcl_itime.h ../common/mcl_blocking_struct.h +mcl_rx_window.o: ../common/mcl_periodic_timer.h ../common/mcl_file_io.h mcl.h +mcl_rx_window.o: mcl_error.h ../common/rse_fec.h ../../../ldpc/src/ldpc_fec.h +mcl_rx_window.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_rx_window.o: ../../../ldpc/src/tools.h +mcl_rx_window.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_rx_window.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +mcl_rx_window.o: mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h +mcl_rx_window.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +mcl_rx_window.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_rx_window.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_sig.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_sig.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_sig.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_sig.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_sig.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_sig.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_sig.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_sig.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_sig.o: ../../../ldpc/src/ldpc_fec.h +mcl_sig.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_sig.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_sig.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h mcl_flid_sl.h +mcl_sig.o: mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +mcl_sig.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h mcl_rx_window.h +mcl_sig.o: mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h mcl_meta_object.h +mcl_sig.o: mcl_meta_object_layer.h +mcl_network.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_network.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_network.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_network.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_network.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_network.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_network.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_network.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_network.o: ../../../ldpc/src/ldpc_fec.h +mcl_network.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_network.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_network.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_network.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_network.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_network.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +mcl_network.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h +mcl_du.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_du.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_du.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_du.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_du.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_du.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_du.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_du.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_du.o: ../../../ldpc/src/ldpc_fec.h ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_du.o: ../../../ldpc/src/tools.h ../../../ldpc/src/ldpc_create_pchk.h +mcl_du.o: mcl_lib.h mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_du.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_du.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h +mcl_du.o: mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_du.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_adu.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_adu.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_adu.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_adu.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_adu.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_adu.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_adu.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_adu.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_adu.o: ../../../ldpc/src/ldpc_fec.h +mcl_adu.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_adu.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_adu.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h mcl_flid_sl.h +mcl_adu.o: mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +mcl_adu.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h mcl_rx_window.h +mcl_adu.o: mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h mcl_meta_object.h +mcl_adu.o: mcl_meta_object_layer.h +mcl_stats.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_stats.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_stats.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_stats.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_stats.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_stats.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_stats.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_stats.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_stats.o: ../../../ldpc/src/ldpc_fec.h +mcl_stats.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_stats.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_stats.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +mcl_stats.o: mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h +mcl_stats.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +mcl_stats.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_stats.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_fec.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_fec.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_fec.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_fec.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_fec.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_fec.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_fec.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_fec.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_fec.o: ../../../ldpc/src/ldpc_fec.h +mcl_fec.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_fec.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_fec.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h mcl_flid_sl.h +mcl_fec.o: mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +mcl_fec.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h mcl_rx_window.h +mcl_fec.o: mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h mcl_meta_object.h +mcl_fec.o: mcl_meta_object_layer.h +mcl_fsm.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_fsm.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_fsm.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_fsm.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_fsm.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_fsm.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_fsm.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_fsm.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_fsm.o: ../../../ldpc/src/ldpc_fec.h +mcl_fsm.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_fsm.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_fsm.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h mcl_flid_sl.h +mcl_fsm.o: mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +mcl_fsm.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h mcl_rx_window.h +mcl_fsm.o: mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h mcl_meta_object.h +mcl_fsm.o: mcl_meta_object_layer.h +mcl_flute.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_flute.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_flute.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_flute.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_flute.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_flute.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_flute.o: ../common/mcl_blocking_struct.h ../common/mcl_periodic_timer.h +mcl_flute.o: ../common/mcl_file_io.h mcl.h mcl_error.h ../common/rse_fec.h +mcl_flute.o: ../../../ldpc/src/ldpc_fec.h +mcl_flute.o: ../../../ldpc/src/ldpc_matrix_sparse.h ../../../ldpc/src/tools.h +mcl_flute.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_flute.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +mcl_flute.o: mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h mcl_lct_hdr.h +mcl_flute.o: mcl_alc_hdr.h mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +mcl_flute.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h mcl_fec.h +mcl_flute.o: mcl_meta_object.h mcl_meta_object_layer.h +mcl_meta_object.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_meta_object.o: mcl_profile.h ../common/mcl_defines.h +mcl_meta_object.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_meta_object.o: ../alc/mcl_lib_api_alc.h ../common/mcl_version.h +mcl_meta_object.o: ../common/mcl_addr.h ../common/ssm_for_linux.h +mcl_meta_object.o: ../common/mcl_socket_lib.h ../common/mcl_debug.h +mcl_meta_object.o: ../common/mcl_itime.h ../common/mcl_blocking_struct.h +mcl_meta_object.o: ../common/mcl_periodic_timer.h ../common/mcl_file_io.h +mcl_meta_object.o: mcl.h mcl_error.h ../common/rse_fec.h +mcl_meta_object.o: ../../../ldpc/src/ldpc_fec.h +mcl_meta_object.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_meta_object.o: ../../../ldpc/src/tools.h +mcl_meta_object.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h mcl_data.h +mcl_meta_object.o: mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h mcl_rlc.h +mcl_meta_object.o: mcl_flid_sl.h mcl_socket.h mcl_periodic_proc.h +mcl_meta_object.o: mcl_lct_hdr.h mcl_alc_hdr.h mcl_stats.h mcl_fsm.h +mcl_meta_object.o: mcl_proto.h mcl_rx.h mcl_rx_window.h mcl_flute.h mcl_tx.h +mcl_meta_object.o: mcl_cb.h mcl_fec.h mcl_meta_object.h +mcl_meta_object.o: mcl_meta_object_layer.h +mcl_meta_object_layer.o: mcl_includes.h ../common/mcl_types.h +mcl_meta_object_layer.o: ../common/mcl_osdep.h mcl_profile.h +mcl_meta_object_layer.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_meta_object_layer.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +mcl_meta_object_layer.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_meta_object_layer.o: ../common/ssm_for_linux.h ../common/mcl_socket_lib.h +mcl_meta_object_layer.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_meta_object_layer.o: ../common/mcl_blocking_struct.h +mcl_meta_object_layer.o: ../common/mcl_periodic_timer.h +mcl_meta_object_layer.o: ../common/mcl_file_io.h mcl.h mcl_error.h +mcl_meta_object_layer.o: ../common/rse_fec.h ../../../ldpc/src/ldpc_fec.h +mcl_meta_object_layer.o: ../../../ldpc/src/ldpc_matrix_sparse.h +mcl_meta_object_layer.o: ../../../ldpc/src/tools.h +mcl_meta_object_layer.o: ../../../ldpc/src/ldpc_create_pchk.h mcl_lib.h +mcl_meta_object_layer.o: mcl_data.h mcl_vrmem.h mcl_rx_storage.h mcl_tx_tab.h +mcl_meta_object_layer.o: mcl_rlc.h mcl_flid_sl.h mcl_socket.h +mcl_meta_object_layer.o: mcl_periodic_proc.h mcl_lct_hdr.h mcl_alc_hdr.h +mcl_meta_object_layer.o: mcl_stats.h mcl_fsm.h mcl_proto.h mcl_rx.h +mcl_meta_object_layer.o: mcl_rx_window.h mcl_flute.h mcl_tx.h mcl_cb.h +mcl_meta_object_layer.o: mcl_fec.h mcl_meta_object.h mcl_meta_object_layer.h diff --git a/src/alc/libmclalc.vcproj b/src/alc/libmclalc.vcproj new file mode 100644 index 0000000..ba02310 --- /dev/null +++ b/src/alc/libmclalc.vcproj @@ -0,0 +1,321 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/alc/libmclalc.vcproj.old b/src/alc/libmclalc.vcproj.old new file mode 100644 index 0000000..8d8cecc --- /dev/null +++ b/src/alc/libmclalc.vcproj.old @@ -0,0 +1,285 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/alc/mcl.cpp b/src/alc/mcl.cpp new file mode 100644 index 0000000..82ae319 --- /dev/null +++ b/src/alc/mcl.cpp @@ -0,0 +1,303 @@ +/* $Id: mcl.cpp,v 1.15 2005/05/24 15:43:22 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "mcl_includes.h" + +/****** definition of global MCL variables ******/ + +/* MCL version of standard streams. */ +FILE *mcl_stdout; /* MCL standard output stream */ +FILE *mcl_stderr; /* MCL standard error output stream */ + +char mcl_tmp_dir_name[MAX_FILE_NAME_LEN]; + +const UINT32 mcl_iss = 1; +UINT32 mcl_time_count = 0; + +mcl_periodic_timer mcl_periodic_timer_obj; + + +/****** local static variables ******/ + + +#if 0 +/* private functions */ +static int mcl_init_sender (mcl_cb *mclcb); +static int mcl_init_receiver(mcl_cb *mclcb); +#endif + + +/* + * version # and credits + * edit as appropriate! + */ +void +mcl_moreabout(void) +{ + /* + * credits (very important :-) + */ + PRINT_OUT((mcl_stdout, "\n-- MultiCast Library version 3 (MCLv3) --\n")) + PRINT_OUT((mcl_stdout, MCLv3_VERSION)) + PRINT_OUT((mcl_stdout, " Copyright (c) 1999-2005 INRIA - All rights reserved\n")) + PRINT_OUT((mcl_stdout, " main author/contact: vincent.roca@inrialpes.fr\n")) + PRINT_OUT((mcl_stdout, " web site: http://www.inrialpes.fr/planete/people/roca/mcl/\n")) + PRINT_OUT((mcl_stdout, " MCL comes with ABSOLUTELY NO WARRANTY; This is free software,\n")) + PRINT_OUT((mcl_stdout, " and you are welcome to redistribute it under certain conditions;\n")) + PRINT_OUT((mcl_stdout, " See the GNU General Public License as published by the Free \n")) + PRINT_OUT((mcl_stdout, " Software Foundation, version 2 or later, for more details.\n")) + PRINT_OUT((mcl_stdout, "-- Credits:\n")) + PRINT_OUT((mcl_stdout, "* Vincent Roca, Christoph Neumann, Julien Laboure, Benoit Mordelet\n")) + PRINT_OUT((mcl_stdout, " and many others (see the web site for more details...)\n")) +#ifdef RSE_FEC + PRINT_OUT((mcl_stdout, "* fec.c -- forward error corection based on Vandermonde matrices\n")) + PRINT_OUT((mcl_stdout, " (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it) (980624)\n")) + PRINT_OUT((mcl_stdout, " Portions derived from code by Phil Karn (karn@ka9q.ampr.org),\n")) + PRINT_OUT((mcl_stdout, " Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and\n")) + PRINT_OUT((mcl_stdout, " Hari Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995\n")) +#endif /* RSE_FEC */ +#ifdef LDPC_FEC + { + LDPCFecSession *ldpc_ses = new LDPCFecSession; + ldpc_ses->InitSession(10, 20, 4); /* don't care about args */ + ldpc_ses->MoreAbout(mcl_stdout); + ldpc_ses->EndSession(); + } +#endif /* LDPC_FEC */ + /* + * compilation options + */ + PRINT_OUT((mcl_stdout, "-- Compiled with:\n ")) +#ifdef INET6 + PRINT_OUT((mcl_stdout, "INET6 ")) +#endif + +#ifdef SSM + PRINT_OUT((mcl_stdout, "SSM ")) +#endif + +#ifdef RLC + PRINT_OUT((mcl_stdout, "RLC ")) +#endif + +#ifdef FLIDS + PRINT_OUT((mcl_stdout, "FLID-SL ")) +#endif + +#ifdef RSE_FEC + PRINT_OUT((mcl_stdout, "RSE_FEC ")) +#endif + +#ifdef LDPC_FEC + PRINT_OUT((mcl_stdout, "LDPC_FEC ")) +#endif + +#ifdef POSTPONE_FEC_DECODING + PRINT_OUT((mcl_stdout, "POSTPONE_FEC_DECODING ")) +#endif + +#ifdef LCT_SCHED1 + PRINT_OUT((mcl_stdout, "LCT_SCHED1 ")) +#endif + +#ifdef ANTICIPATED_TX_FOR_PUSH + PRINT_OUT((mcl_stdout, "ANTICIPATED_TX_FOR_PUSH ")) +#endif + +#ifdef VIRTUAL_TX_MEM + PRINT_OUT((mcl_stdout, "VIRTUAL_TX_MEM (%d) ",VIRTUAL_TX_MEM_MAX_BUFFERING_SIZE)) +#endif + +#ifdef VIRTUAL_RX_MEM + PRINT_OUT((mcl_stdout, "VIRTUAL_RX_MEM (%d) ",VIRTUAL_RX_MEM_MAX_BUFFERING_SIZE)) +#endif + +#ifdef DEBUG + PRINT_OUT((mcl_stdout, "DEBUG ")) +#endif + +#ifdef GET_SYSINFO + PRINT_OUT((mcl_stdout, "GET_SYSINFO ")) +#endif + +#ifdef SVSOA_RECV + PRINT_OUT((mcl_stdout, "SVSOA_RECV ")) +#endif + +#ifdef SIMUL_LOSSES + PRINT_OUT((mcl_stdout, "!!!SIMUL_LOSSES!!! ")) +#endif + PRINT_OUT((mcl_stdout, "\n")) +} + + +/** + * emergency exit function. + * do as little as possible as we are in an unknown state... + * @param n int to be returned by exit() + */ +void +mcl_exit (int n) +{ + int id; + mcl_cb *mclcb = NULL; + + PRINT_ERR((mcl_stderr, "mcl_exit: ERROR, exit everything...\n")) + /* find the first valid mclcb first */ + for (id = 0; id < MAX_NB_MCLCB; id++) { + if (mclcb_tab[id] != NULL) { + mclcb = mclcb_tab[id]; + break; + } + } + /* close the vtm/vrm services to destroy the temp files */ +#ifdef VIRTUAL_TX_MEM + if (mclcb) + mcl_vtm_close (mclcb); +#endif +#ifdef VIRTUAL_RX_MEM + if (mclcb) + mclcb->rx_storage.close_vrmem(mclcb); +#endif + exit(n); +} + + +/** + * new_handler function. + */ +static void +mcl_new_handler_func () +{ + PRINT_ERR((mcl_stderr, "mcl_new_handler_func: ERROR, not memory left, exit everything...\n")) + mcl_exit(-1); +} + + +/** + * Global MCL library initialization. + * Done only once. + */ +void +mcl_global_init (void) +{ + // for the one time MCL global initialization + static bool mcl_glob_initialized = false; + + if (mcl_glob_initialized == true) + return; + mcl_glob_initialized = true; + + set_new_handler(mcl_new_handler_func); + mcl_init_random(); + strcat(mcl_tmp_dir_name, MCL_DEFAULT_TMP_DIR_NAME); + + mcl_stdout_stderr_init(); + + /* initialize the session control block table */ + mcl_init_mclcb_tab(); + +#ifdef WIN32 + /* Socket initialisation for WinSock */ + mcl_winsock_init(); +#endif /* WIN32 */ + + /* create and start the global periodic timer service */ + mcl_periodic_timer_obj.start(); + + ASSERT(mcl_iss > 0); /* must be > 0 (0 means non initialized) */ +} + + +/** + * Initialize the mcl_stdout and mcl_stderr outputs. + * Assumes that the mcl_tmp_dir_name global variable is already initialized. + */ +void +mcl_stdout_stderr_init (void) +{ +#ifdef STDOUT_TO_FILE + char stdout_name[MAX_FILE_NAME_LEN]; +#endif + +#ifdef STDOUT_TO_FILE + memset(stdout_name, 0, MAX_FILE_NAME_LEN); + strncat(stdout_name, mcl_tmp_dir_name, MAX_FILE_NAME_LEN); + strncat(stdout_name, "/mcl_out.txt", MAX_FILE_NAME_LEN); + /* create temp file now in the tmp dir specified in mcl_tmp_dir_name */ +#ifdef WIN32 + if ((mcl_stdout = open(vcb->f_name, _O_RDWR | O_CREAT | O_BINARY)) < 0) { + perror("mcl_glob_init: ERROR, cannot open mlc_out.trc file"); + mcl_exit(-1); + } +#else /* UNIX case */ + if ((mcl_stdout = fopen(stdout_name, "w")) == NULL) { +printf("error: cannot open %s\n", stdout_name); + perror("mcl_glob_init: ERROR, cannot open mlc_out.trc file"); + mcl_exit(-1); + } +#endif /* OS */ + mcl_stderr = mcl_stdout; /* err is the same then */ +#else /* STDOUT_TO_FILE */ + mcl_stdout = stdout; + mcl_stderr = stderr; +#endif /* STDOUT_TO_FILE */ +} + + + +#if 0 + + + +/* + * initialize the receiving context... + */ +static int +mcl_init_receiver (mcl_cb *mclcb) /* session cb */ +{ + TRACELVL(5, (mcl_stdout, "-> mcl_init_receiver: id=%d\n", + mclcb->get_id())) + mclcb->rxlvl.socket_head = mclcb->socket_tab; + mclcb->rxlvl.next_adu2give = NULL; /* not yet known */ + mclcb->rxlvl.next_adu2give_seq = mcl_iss; + /* + * ... and create the reception thread and lock. + */ + +#ifdef WIN32 + if (CreateThread(THREAD_ALL_ACCESS, 0, (LPTHREAD_START_ROUTINE) mcl_rx_thread, (void*)mclcb, 0, (LPDWORD)&mclcb->rx_thread) == NULL) { + perror("mcl_init_receiver: CreateThread"); + mcl_exit(1); + } +#else + if ((pthread_create((pthread_t*)&mclcb->rx_thread, NULL, mcl_rx_thread, (void*)mclcb)) != 0) { + perror("mcl_init_receiver: pthread_create"); + mcl_exit(1); + } +#endif + TRACELVL(5, (mcl_stdout, "<- mcl_init_receiver: OK\n")) + return 0; +} + + +#endif diff --git a/src/alc/mcl.h b/src/alc/mcl.h new file mode 100644 index 0000000..01e6070 --- /dev/null +++ b/src/alc/mcl.h @@ -0,0 +1,122 @@ +/* $Id: mcl.h,v 1.7 2005/03/18 12:06:15 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_H /* { */ +#define MCL_H + + +/****** general purpose enumerations ******************************************/ + +/** + * Used to differentiate between sending and receiving variants when needed. + */ +enum mcl_tx_or_rx { + MCL_RX = 0, + MCL_TX = 1 +}; + +#define SENDER MCL_TX +#define RECEIVER MCL_RX + + +/****** constants: do not edit ************************************************/ + +/* + * print stats every STATS_PERIOD usec at most + */ +#define STATS_PERIOD 5000000 + +/* + * call the memory cleanup functin with this period (in time tick) + */ +#define TX_MEM_CLEANUP_PERIOD 50 + +#if 0 +/* + * sender or receiver; used as argument to some functions + * do not change... + */ +#define SENDER 1 +#define RECEIVER 0 +#endif + +/* + * used by mcl_drop_layer; check or really drop ? + */ +#define MCL_CHECK_ONLY 1 +#define MCL_DO_IT 0 +#define MCL_ALL_LAYERS 254 /* used by add/drop functions */ +#define MCL_HIGHEST_LAYER 255 /* used by add/drop functions */ + +/* + * tx/rx modes + * differentiate application mode and signaling mode (usually piggy-backed) + */ +#define MODE_UNI_TX 0x01 /* can send in unicast */ +#define MODE_MCAST_TX 0x02 /* can send in multicast */ +#define MODE_UNI_RX 0x04 /* can receive in unicast */ +#define MODE_MCAST_RX 0x08 /* can receive in multicast */ + /* SIG currently only used by ODL but */ +//#define MODE_SIG_UNI_TX 0x10 /* can send signaling in unicast */ +//#define MODE_SIG_UNI_RX 0x20 /* can recv signaling in unicast */ + +/* + * How many times should we transmit each kind of signalization information + * (for increased reliability) ? Tx for ever if value is -1. + * NB: for CLOSE the nb of tx must be > 0 (10 times seems ok) + */ +#define MAX_TX_EXT_NONEWADU -1 +#define MAX_TX_SIG_CLOSE 10 + + +/****** prototypes ************************************************************/ + +extern void mcl_moreabout (void); +extern void mcl_exit (INT32 n); +extern void mcl_global_init (void); +extern void mcl_stdout_stderr_init (void); + + +/****** global variables shared by all sessions *******************************/ + +/** MCL version of standard output stream. */ +extern FILE *mcl_stdout; +/** MCL version of standard error stream. */ +extern FILE *mcl_stderr; + +/** Initial sequence number */ +extern const UINT32 mcl_iss; +/** + * Local time in usec. + * Incremented by the period_proc thread. + */ +extern UINT32 mcl_time_count; + +extern mcl_thread_t mcl_timer_thread_id; + +/** default temporary file location. */ +extern char mcl_tmp_dir_name[MAX_FILE_NAME_LEN]; + +extern class mcl_periodic_timer mcl_periodic_timer_obj; + + +#endif /* } MCL_H */ + diff --git a/src/alc/mcl_adu.cpp b/src/alc/mcl_adu.cpp new file mode 100644 index 0000000..50c955a --- /dev/null +++ b/src/alc/mcl_adu.cpp @@ -0,0 +1,545 @@ +/* $Id: mcl_adu.cpp,v 1.20 2005/03/18 12:06:15 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "mcl_includes.h" + + +/* + * Create and init a new adu struct. + */ +adu_t * +mcl_create_adu (mcl_cb *mclcb) +{ + adu_t *adu; + + if (!(adu = (adu_t*)calloc(1, sizeof(adu_t)))) { + PRINT_ERR((mcl_stderr, "mcl_create_adu: ERROR, no memory")) + mcl_exit(-1); + } + adu->addr.reset(); + return (adu); +} + + +/* + * Insert the ADU in the adu list. + */ +void +mcl_insert_adu (mcl_cb *mclcb, + adu_t *adu, + adu_t **list) +{ + adu_t *adul; + + ASSERT(adu && list); + TRACELVL(5, (mcl_stdout, "-> mcl_insert_adu: adu=x%x, seq=%d\n", (int)adu, adu->seq)) + if (!(*list)) { + /* + * first adu in list + */ + *list = adu; + adu->next = adu->prev = adu; + TRACELVL(5, (mcl_stdout, "<- mcl_insert_adu: only one in list\n")) + return; + } + adul = (*list)->prev; + ASSERT(adul); + /* + * start from the highest seq number + */ + for (; adu->seq < adul->seq; adul = adul->prev) { + if (adul == *list) { + /* we have cycled, so adu must be the first of list */ + *list = adu; + adu->next = adul; + adu->prev = adul->prev; + adul->prev->next = adu; + adul->prev = adu; + TRACELVL(5, (mcl_stdout, "<- mcl_insert_adu: at start of list\n")) + return; + } + } + //ASSERT(adu->seq != adul->seq); /* no duplicated adu for the present */ + adu->next = adul->next; + adul->next->prev = adu; + adul->next = adu; + adu->prev = adul; + TRACELVL(5, (mcl_stdout, "<- mcl_insert_adu: ok\n")) +} + + +/* + * Remove an ADU from the adu list + */ +void +mcl_remove_adu (mcl_cb *mclcb, + adu_t *adu, + adu_t **list) +{ + adu_t *prev, *next; + + ASSERT(adu && list); + TRACELVL(5, (mcl_stdout, "-> mcl_remove_adu: adu=x%x, seq=%d\n", (int)adu,adu->seq)) + ASSERT(*list); + prev = adu->prev; + next = adu->next; + if (prev == adu) { /* only one ADU in list */ + ASSERT(next == adu); + *list = NULL; /* list is now empty */ + } else { + prev->next = next; + next->prev = prev; + if (*list == adu) { + *list = next; /* adu was the first in list */ + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_remove_adu:\n")) +} + + +/* + * Returns 1 if the adu has JUST been completely received (decoded or not), + * 0 otherwise. + */ +int +mcl_rx_new_completed_adu (mcl_cb *mclcb, + adu_t *adu) +{ + block_t *blk; + int i; + mcl_adu_rx_status new_status; + + TRACELVL(5, (mcl_stdout, "-> mcl_rx_new_completed_adu:\n")) + ASSERT(adu); /* for tests, but could happen in case of tx errors */ + if (adu->rx_status >= ADU_STATUS_COMPLETED) { + /* in COMPLETED, DECODED, or DELIVERED mode */ + /* we have already recvd everything */ + TRACELVL(5, (mcl_stdout, "<- mcl_rx_new_completed_adu: already completed\n")) + return 0; + } + new_status = ADU_STATUS_DECODED; + for (i = adu->blocking_struct.block_nb, blk = adu->block_head; i > 0; i--, blk++) { + if (blk->rx_status != BLK_STATUS_COMPLETED && + blk->rx_status != BLK_STATUS_DECODED) { + TRACELVL(5, (mcl_stdout, "<- mcl_rx_new_completed_adu: no\n")) + return 0; + } + if (blk->rx_status == BLK_STATUS_COMPLETED) { + /* at least one blk is not decoded, remember it */ + new_status = ADU_STATUS_COMPLETED; + } + if (i == 1) { + /* we have cycled, yes this is a new completed ADU! */ + break; + } + } + /* + * we have everything. Update status and stats... + */ + adu->rx_status = new_status; + mclcb->stats.finish_times[mclcb->stats.finish_index][STATS_FIN_TIME] = mcl_time_count; + mclcb->stats.finish_times[mclcb->stats.finish_index][STATS_SEQ] = adu->seq; + if (++(mclcb->stats.finish_index) == MAX_FIN_TIME) + mclcb->stats.finish_index = 0; + mclcb->stats.adus_compl++; + TRACELVL(5, (mcl_stdout, "<- mcl_rx_new_completed_adu: yes\n")) + return 1; +} + + +/* + * Returns NULL if this ADU has never been announced before, the + * adu_t descriptor otherwise. + * Used only by the receivers. + * If parameter FDT_instanceid is -1, don't care for instance ID when searching + * ADU, and take the first ADU with the specified sequence number seq + */ +adu_t* +mcl_find_adu (mcl_cb *mclcb, + UINT32 seq, + INT32 FDT_instanceid, + adu_t *list) +{ + adu_t *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_find_adu: seq=%d\n", seq)) + if (!list) { + TRACELVL(5, (mcl_stdout, "<- mcl_find_adu: empty list\n")) + return NULL; + } + if (mclcb->findadu_cache && mclcb->findadu_cache->seq == seq && + ((INT32) mclcb->findadu_cache->FDT_instanceid == FDT_instanceid || FDT_instanceid == -1)) { + TRACELVL(5, (mcl_stdout, "<- mcl_find_adu: found in cache\n")) + return mclcb->findadu_cache; + } + /* + * start from the highest seq number + */ + adu = list->prev; + while (1) { + ASSERT(adu); + if (adu->seq == seq && ((INT32) adu->FDT_instanceid == FDT_instanceid || FDT_instanceid == -1)) { + /* found */ + mclcb->findadu_cache = adu; + TRACELVL(5, (mcl_stdout, "<- mcl_find_adu: found\n")) + return adu; + } + if (adu == list || adu->seq < seq) { + /* we have cycled or new adu cannot be in list */ + TRACELVL(5, (mcl_stdout, "<- mcl_find_adu: new\n")) + return NULL; + } + adu = adu->prev; + } +} + + +/* + * Returns NULL if this block has never been announced before, the + * block_t descriptor otherwise. + * Used only by the receivers. + */ +block_t* +FindBlock (mcl_cb *mclcb, + UINT32 seq, + block_t *list, /* in fact this is a tab, not a list! */ + adu_t *adu) +{ + TRACELVL(5, (mcl_stdout, "-> FindBlock: seq=%d\n", seq)) + if (!list) + return NULL; + if (seq < 0 || seq > adu->blocking_struct.block_nb) { + TRACELVL(5, (mcl_stdout, "<- FindBlock: ERROR, out of bound\n")) + return NULL; + } else { + TRACELVL(5, (mcl_stdout, "<- FindBlock: found\n")) + return (list + seq); + } +} + + +/* + * Returns the highest ADU TOI of this list. + */ +int +mcl_get_highest_toi (mcl_cb *mclcb, + adu_t *list) +{ + ASSERT(list); + return list->prev->seq; +} + + +/* + * Segment the ADU in blocks (ie. block_t) and packets (ie. du_t) + * Static info of the adu struct (seq, len, symbol_size) must be + * initialized upon calling this function. + * Used only by the sender. + */ +void +mcl_tx_segment_adu (mcl_cb *mclcb, + adu_t *adu) +{ + block_t *blk; + du_t *du; + UINT32 tot_blk_nb; /* total nb of blocks required */ + UINT32 blk_seq; /* block seq number */ + UINT32 tot_du_nb; /* total nb of DUs required */ + UINT32 k_for_this_blk; + UINT32 i; +#ifdef LDPC_FEC + UINT32 fec_key; +#endif + int rem; + char *ptr; + mcl_blocking_struct_t *bs; + + /* + * max blk size in DU, and max_n. Both values depend on the FEC codec. + * remember it, it will be used for EXT_FTI generation + */ + adu->max_k = mclcb->fec.get_k(); + adu->max_n = mclcb->fec.get_n(); + /* + * compute the blocking struct + */ + bs = &(adu->blocking_struct); + mcl_compute_blocking_struct(adu->max_k, adu->len, adu->symbol_len, bs); + /* + * segment the ADU... + * do it simply: allocate a tab of du_t and block_t structs + * rather than two linked lists! + */ + tot_du_nb = (int)ceil((double)adu->len / (double)adu->symbol_len); + ASSERT(tot_du_nb == bs->I * bs->A_large + (bs->block_nb - bs->I) * bs->A_small); + if (!(du = (du_t*)calloc(tot_du_nb, sizeof(du_t)))) { + goto no_memory; + } + tot_blk_nb = bs->block_nb; + ASSERT(tot_blk_nb == (UINT32)ceil((double)tot_du_nb / (double)adu->max_k)); + if (!(blk = (block_t*)calloc(tot_blk_nb, sizeof(block_t)))) { + goto no_memory; + } + adu->block_head = blk; + +#ifdef LDPC_FEC + /* + * All blocks of one ADU must use the same FEC key! + * Because of FTI limitations (only one value carried). + */ + fec_key = random(); /* 32bit random value */ +#endif + + ptr = adu->data; + rem = adu->len; + for (blk_seq = 0; blk_seq < tot_blk_nb; blk_seq++) { + if (blk_seq < bs->I) + k_for_this_blk = bs->A_large; + else + k_for_this_blk = bs->A_small; + blk->adu = adu; + blk->seq = blk_seq; + blk->du_head = du; + blk->k = k_for_this_blk; +#ifdef LDPC_FEC + blk->fec_key = fec_key; +#endif + /* blk->fec_du_head and fec_du_nb_in_list already set to 0 */ + for (i = 0; i < k_for_this_blk; i++, du++) { + du->block = blk; + du->seq = i; + du->len = min(rem, mclcb->get_payload_size()); +#ifdef VIRTUAL_TX_MEM + du->vtm_info.du_in_seq_in_txtab = 1; /*default*/ + if (adu->vtm_info.in_vtm) { + ASSERT(mclcb->vtm_used); + mcl_vtm_register_du(mclcb, du, + (UINT32)(ptr - adu->data)); + /* also sets du->data to NULL */ + } else +#endif /* VIRTUAL_TX_MEM */ + du->data = ptr; + ptr += du->len; + rem -= du->len; + blk->len += du->len; /* last DU may be non full-sized */ + } + blk++; /* switch to next block */ + } + ASSERT(rem == 0); + if (mclcb->get_verbosity() >= 3) { + PRINT_OUT((mcl_stdout, + "New ADU: seq=%d, len=%d, max_k=%d, symbol_size=%d\n", + adu->seq, adu->len, + adu->block_head->k, adu->symbol_len)) +#if defined(LDPC_FEC) && defined(DEBUG) + if (mclcb->fec.get_fec_code() == + MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0 || + mclcb->fec.get_fec_code() == + MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1) { + TRACELVL(4, (mcl_stdout, + " New ADU: LDPC/LDGM key=%d\n", + adu->block_head->fec_key)) + } +#endif + TRACELVL(4, (mcl_stdout, " New ADU: %d blocks, max_block_len=%d (%d DUs), last_block_len=%d (%d DUs)\n", + adu->blocking_struct.block_nb, adu->block_head->len, adu->block_head->k, + (blk-1)->len, (blk-1)->k)) + } + return; + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_tx_segment_adu: ERROR, no memory")) + mcl_exit(-1); +} + + +/* + * Free all buffers for this transmission ADU. + * WARNING: this is the sending side function, do not use for a receiver! + * WARNING: does not remove the ADU struct from the linked list of ADUs + * WARNING: does not free the ADU buffer + */ +void +mcl_tx_free_this_adu (mcl_cb *mclcb, + adu_t *adu) +{ + block_t *blk; + UINT32 i; +#ifdef FEC + UINT32 j; + du_t *du; +#endif /* FEC */ + + ASSERT(adu); + TRACELVL(5, (mcl_stdout, "-> mcl_tx_free_this_adu: adu=x%x, aseq=%d\n", + (int)adu, adu->seq)) + ASSERT(mclcb->is_a_sender()); + /* + * step1: free all DUs from each block + */ + for (i = 0, blk = adu->block_head; i < adu->blocking_struct.block_nb; i++, blk++) { + /* no data block here, only points in the global data block */ + ASSERT((blk)) + if (blk->k > 0) { + if (i == 0) { + /* in fact single du table (ie malloc) */ + ASSERT(blk->du_head); + free(blk->du_head); + } + blk->du_head = NULL; + blk->k = 0; + } +#ifdef FEC + /* + * FEC DUs data blocks are allocated in several independant + * mallocs, but the FEC DU structs in a single block. + */ + for (j = 0, du = blk->fec_du_head; j < blk->fec_du_nb_in_list; + j++, du++) { + ASSERT((du)) +#ifdef VIRTUAL_TX_MEM + if (!mclcb->vtm_used || !du->vtm_info.in_vtm) +#endif + { + ASSERT((du->data)) + free(du->data); + du->data = NULL; + } + } + if (blk->fec_du_head) { + free(blk->fec_du_head); + blk->fec_du_head = NULL; + blk->fec_du_nb_in_list = 0; + } +#endif /* FEC */ + } + /* + * step2: free the block table + */ + if (adu->blocking_struct.block_nb > 0) { + ASSERT((adu->block_head)) + free(adu->block_head); + adu->block_head = NULL; + adu->blocking_struct.block_nb = 0; + } + /* + * step3: free data buffer + */ +#ifdef VIRTUAL_TX_MEM + if (!mclcb->vtm_used || !adu->vtm_info.in_vtm) +#endif + { + if (adu->data) { + free(adu->data); + adu->data = NULL; + mclcb->stats.buf_space -= adu->len; /* update stats */ + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx_free_this_adu: ok\n")) +} + + +/** + * Free all buffers for this reception ADU. + * WARNING: this is the receiving side function, do not use for a sender! + * WARNING: does not remove the ADU struct from the linked list of ADUs + * WARNING: does not free the ADU buffer + */ +void +mcl_rx_free_this_adu (mcl_cb *mclcb, + adu_t *adu) +{ + block_t *blk; + UINT32 i; +#ifdef FEC + UINT32 j; + du_t *du; +#endif /* FEC */ + + ASSERT(adu); + TRACELVL(5, (mcl_stdout, "-> mcl_rx_free_this_adu: adu=x%x, aseq=%d\n", + (int)adu, adu->seq)) + ASSERT(mclcb->is_a_receiver()); + /* + * step1: free all DUs from each block + */ + for (i = 0, blk = adu->block_head; i < adu->blocking_struct.block_nb; i++, blk++) { + /* + * FEC DUs data blocks and source DUs data blocks are + * allocated separately, upon packet reception/decoding. + */ +#ifdef FEC + for (j = 0, du = blk->fec_du_head; j < blk->fec_du_nb_in_list; + j++, du = du->next) { + ASSERT((du)) + mclcb->rx_storage.free_data(mclcb, du); + } +#endif /* FEC */ + for (j = 0, du = blk->du_head; j < blk->du_nb_in_list; + j++, du = du->next) { + ASSERT((du)) + mclcb->rx_storage.free_data(mclcb, du); + } + } + /* + * step2: free the block table + */ + if (adu->blocking_struct.block_nb > 0) { + ASSERT((adu->block_head)) + free(adu->block_head); + adu->block_head = NULL; + adu->blocking_struct.block_nb = 0; + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx_free_this_adu: ok\n")) +} + + +#if 0 +/** + * Free all ADUs. + */ +void +mcl_free_all_adu (mcl_cb *mclcb) +{ + adu_t *adu; + txlay_t *tl; + //int i; + + if (mclcb->is_a_sender()) { + mclcb->tx.free_all_adu(mclcb); +#if 0 + /* ADUs are only stored on the base txlvl structure */ + tl = mclcb->txlay_tab; + while ((adu = tl->adu_head) != NULL) { + mcl_remove_adu(mclcb, adu, &(tl->adu_head)); + mcl_tx_free_this_adu(mclcb, adu); + free(adu); /* and free the buffer */ + } +#endif + } + if (mclcb->is_a_receiver()) { + /* nothing yet */ + /* XXX: TODO ! */ + } +} +#endif + diff --git a/src/alc/mcl_alc_hdr.cpp b/src/alc/mcl_alc_hdr.cpp new file mode 100644 index 0000000..af59a7c --- /dev/null +++ b/src/alc/mcl_alc_hdr.cpp @@ -0,0 +1,252 @@ +/* $Id: mcl_alc_hdr.cpp,v 1.9 2005/01/11 13:12:25 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "mcl_includes.h" + + +static int alc_hdr_add_FPI_he (mcl_cb *mclcb, char *ptr, int hlen, + hdr_infos_t *hdr_infos); + +static int alc_hdr_parse_FPI_he (mcl_cb *mclcb, char *ptr, int hlen, int plen, + hdr_infos_t *hdr_infos); + + +/****** sending side **********************************************************/ + + +/** + * Initializes the ALC header. + * => See header file for more informations. + */ +int +alc_hdr_create (mcl_cb *mclcb, + fixed_lct_hdr_t *lct_hdr, + hdr_infos_t *hdr_infos) +{ + int hlen; /* length of the fixed+variable_len headers */ + + TRACELVL(5, (mcl_stdout, "-> alc_hdr_create:\n")) + if ((hlen = lct_hdr_create(mclcb, lct_hdr, hdr_infos)) < 0) { + goto bad; + } + if (hdr_infos->FPI_present) { + hlen = alc_hdr_add_FPI_he(mclcb, (char*)lct_hdr, hlen, hdr_infos); + } + TRACELVL(5, (mcl_stdout, "<- alc_hdr_create:\n")) + return hlen; + +bad: + TRACELVL(5, (mcl_stdout, "<- alc_hdr_create: ERROR\n")) + return -1; + +} + + +/* + * Add a FPI extension, using the provided hdr_infos. + * + * with FEC_ENCODING_ID_SMALL_LARGE_EXP_FEC (128) and + * FEC_ENCODING_ID_LDPC_FEC (140): + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | source block ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |F| encoding symbol ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * the F flag, if set, indicates that it is a FEC symbol + * + * + * with FEC_ENCODING_ID_SMALL_SYSTEMATIC_FEC (129): + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | source block ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | source block length | encoding symbol ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * + * with FEC_ENCODING_ID_NO_FEC: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | source block ID | encoding symbol ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Returns the new size of the header (bytes) with this + * header extension, or -1 if error. + */ +static int +alc_hdr_add_FPI_he (mcl_cb *mclcb, + char *ptr, /* write at ptr+hlen then update hlen */ + int hlen, + hdr_infos_t *hdr_infos) +{ + UINT32 word = 0; + + TRACELVL(5, (mcl_stdout, "-> alc_hdr_add_FPI_he:\n")) + ASSERT(hdr_infos); + switch (hdr_infos->fec_encoding_id) { + case FEC_ENCODING_ID_PCM_FEC: + case FEC_ENCODING_ID_SMALL_LARGE_EXP_FEC: + /* 64 bit of FPI */ + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->idf_block); + hlen += 4; + word = ((hdr_infos->is_fec ? 1 : 0) << 31) | + (hdr_infos->idf_du & 0x7FFFFFFF); + *(UINT32*)(ptr + hlen) = htonl(word); + hlen += 4; + break; + + case FEC_ENCODING_ID_SMALL_SYSTEMATIC_FEC: + /* 64 bit of FPI */ + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->idf_block); + hlen += 4; + word = ((hdr_infos->k) << 16) | + (hdr_infos->idf_du & 0xFFFF); + *(UINT32*)(ptr + hlen) = htonl(word); + hlen += 4; + break; + + case FEC_ENCODING_ID_NO_FEC: + /* 32 bit of FPI */ + word = ((hdr_infos->idf_block & 0X0000FFFF) << 16) | + (hdr_infos->idf_du & 0x0000FFFF); + *(UINT32*)(ptr + hlen) = htonl(word); + hlen += 4; + break; + + default: + ASSERT(0); + } + TRACELVL(5, (mcl_stdout, "<- alc_hdr_add_FPI_he: hlen=%d\n", hlen)) + return hlen; +} + + +/****** receiving side ********************************************************/ + + +/** + * Parses the ALC header of the received packet. + * => See header file for more informations. + */ +int +alc_hdr_parse (mcl_cb *mclcb, + fixed_lct_hdr_t *lct_hdr, + hdr_infos_t *hdr_infos, + int plen) /* packet len (data+rlc+alc headers) */ +{ + int hlen; + + TRACELVL(5, (mcl_stdout, "-> alc_hdr_parse:\n")) + if ((hlen = lct_hdr_parse(mclcb, lct_hdr, hdr_infos)) < 0) { + goto bad_hdr; + } + if (plen > hlen) { + if ((hlen = alc_hdr_parse_FPI_he(mclcb, (char*)lct_hdr, hlen, + plen, hdr_infos)) < 0) { + goto bad_hdr; + } + } + TRACELVL(5, (mcl_stdout, "<- alc_hdr_parse: \n")) + return hlen; + +bad_hdr: + PRINT_ERR((mcl_stderr, "alc_hdr_parse: ERROR, bad header, dropped\n")) + TRACELVL(5, (mcl_stdout, "<- alc_hdr_parse: error\n")) + return -1; +} + + +static int +alc_hdr_parse_FPI_he (mcl_cb *mclcb, + char *ptr, /* read at ptr+hlen */ + int hlen, + int plen, + hdr_infos_t *hdr_infos) +{ + UINT32 word; + + TRACELVL(5, (mcl_stdout, "-> alc_hdr_parse_FPI_he:\n")) + switch (hdr_infos->fec_encoding_id) { + case FEC_ENCODING_ID_PCM_FEC: + case FEC_ENCODING_ID_SMALL_LARGE_EXP_FEC: + /* 64 bit of FPI */ + if (plen < hlen + 8) { + TRACELVL(5, (mcl_stdout, + " alc_hdr_parse_FPI_he: ERROR, too short with FEC Enc.ID 129/140 (expected %d, actual len %d)\n", + hlen + 8, plen)) + return -1; + } + hdr_infos->idf_block = ntohl(*(int*)(ptr + hlen)); + hlen += 4; + word = ntohl(*(int*)(ptr + hlen)); + hdr_infos->is_fec = (word & 0x80000000) ? true : false; + hdr_infos->idf_du = (word & 0x7FFFFFFF); + hlen += 4; + break; + + case FEC_ENCODING_ID_SMALL_SYSTEMATIC_FEC: + /* 64 bit of FPI */ + if (plen < hlen + 8) { + TRACELVL(5, (mcl_stdout, + " alc_hdr_parse_FPI_he: ERROR, too short with FEC Enc.ID 129 (expected %d, actual len %d)\n", + hlen + 8, plen)) + return -1; + } + hdr_infos->idf_block = ntohl(*(int*)(ptr + hlen)); + hlen += 4; + word = ntohl(*(int*)(ptr + hlen)); + hdr_infos->k = (word & 0xFFFF0000) >> 16; + hdr_infos->idf_du = (word & 0x0000FFFF); + hdr_infos->is_fec = (hdr_infos->idf_du >= hdr_infos->k) ? true : false; + hlen += 4; + break; + + case FEC_ENCODING_ID_NO_FEC: + /* 32 bit of FPI */ + if (plen < hlen + 4) { + TRACELVL(5, (mcl_stdout, + " alc_hdr_parse_FPI_he: ERROR, too short with FEC Enc. ID 0 (expected %d, actual len %d)\n", + hlen + 4, plen)) + return -1; + } + word = ntohl(*(int*)(ptr + hlen)); + hdr_infos->idf_block = (word >> 16); + hdr_infos->is_fec = false; /* no FEC here */ + hdr_infos->idf_du = (word & 0x0000FFFF); + hlen += 4; + break; + + default: + ASSERT(0); /* should have already been checked */ + } + hdr_infos->FPI_present = true; + TRACELVL(5, (mcl_stdout, "<- alc_hdr_parse_FPI_he: hlen=%d\n", hlen)) + return hlen; +} + diff --git a/src/alc/mcl_alc_hdr.h b/src/alc/mcl_alc_hdr.h new file mode 100644 index 0000000..97e556d --- /dev/null +++ b/src/alc/mcl_alc_hdr.h @@ -0,0 +1,63 @@ +/* $Id: mcl_alc_hdr.h,v 1.4 2005/01/11 13:12:26 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#ifndef MCL_ALC_HDR_H /* { */ +#define MCL_ALC_HDR_H + + +#define ALC_VERSION 0 + + +/** + * Initializes the ALC header. + * Assumes that the memory block has been allocated by the caller + * who MUST ensure that it will be large enough to hold all the + * possible fields! + * @param mclcb + * @param lct_hdr pointer to the LCT header + * @param hdr_infos pointer to the control struct containing raw + * used during ALC header creation + * @return returns the size of the ALC header (bytes), or + * -1 if error. + */ + +extern int alc_hdr_create (class mcl_cb *mclcb, + fixed_lct_hdr_t *lct_hdr, + hdr_infos_t *hdr_infos); + + +/** + * Parses the ALC header of the received packet. + * @param mclcb + * @param lct_hdr pointer to the LCT header + * @param hdr_infos pointer to the control struct containing raw + * used during ALC header creation + * @return returns the size of the ALC header (bytes), or + * -1 if error. + */ +extern int alc_hdr_parse (class mcl_cb *mclcb, + fixed_lct_hdr_t *lct_hdr, + hdr_infos_t *hdr_infos, + INT32 plen); + + +#endif /* } MCL_ALC_HDR_HALC */ diff --git a/src/alc/mcl_cb.cpp b/src/alc/mcl_cb.cpp new file mode 100644 index 0000000..fd86dcf --- /dev/null +++ b/src/alc/mcl_cb.cpp @@ -0,0 +1,652 @@ +/* $Id: mcl_cb.cpp,v 1.34 2005/05/24 15:43:22 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + +/* + * mcl_cb class implementation + */ + +/* the MCL control block table is defined here... */ +mcl_cb *mclcb_tab[MAX_NB_MCLCB]; + +/* + * One time initialization of the mclcb_tab. + * => See header file for more informations. + */ +void +mcl_init_mclcb_tab (void) +{ +#ifdef DEBUG + static bool init = false; + + ASSERT(init == false); // check that it is called only once + init = true; +#endif + /* the session control block table */ + memset(mclcb_tab, 0, sizeof(mclcb_tab)); +} + + + +/* + * Session control block constructor. + * => See header file for more informations. + */ +mcl_cb::mcl_cb (mcl_tx_rx_mode mode) +{ + INT32 i; + INT32 prof; /* temp */ +#if 0 + /* + * Tx rate scale (how many DUs to send on each layer at each time tick) + * Use the power of 2 scale of tx rate (default), or a custom scale. + * XXX: adjust the nb of preinitialized elements according to + * MAX_NB_TX_LAYERS, otherwise it generates a warning! + */ + INT32 du_per_tick_scale[MAX_NB_TX_LAYERS]; // predefined tx rate scale +#endif + + + mcl_global_init(); // global MCL initialization, if not already + // performed. Otherwise it does nothing. + + this->fully_initialized = false; // not yet... + /* + * get a unique identifier in the file descriptor space + */ + if ((this->id = (INT32)dup(0)) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_cb::mcl_cb: ERROR cannot create a new session identifier\n")) + goto bad; + } + if (this->id >= MAX_NB_MCLCB) { + PRINT_ERR((mcl_stderr, + "mcl_cb::mcl_cb: ERROR too many opened session, MCL file descriptor space full\n")) + PRINT_ERR((mcl_stderr, + "Recompile the MCL-ALC lib with a higher MAX_NB_MCLCB (src/alc/mcl_profile.h)\n")) + goto bad; + } + /* + * store the new mclcb in the tab + */ + ASSERT(mclcb_tab[this->id] == NULL); + mclcb_tab[this->id] = this; + + /* + * various mode initialization + */ + this->tx_rx_mode = mode; + this->flute_mode = false; + this->verbosity_level = 0; + //this->verbosity_level = 5; // for tests... set to maximum + this->stats_level = 0; + //this->stats_level = 2; // for tests... set to maximum + + /* + * FSM initialization + */ + switch (this->tx_rx_mode) { + case MCL_IS_A_SENDER_ONLY: + this->fsm.update_tx_state(this, TEVENT_OPEN_CALLED); + // can't call init_sender() here because of param parsing + break; + case MCL_IS_A_RECEIVER_ONLY: + this->fsm.update_rx_state(this, REVENT_OPEN_CALLED); + // can't call init_receiver() here because of param parsing + break; + default: + PRINT_ERR((mcl_stderr, + "mcl_cb::mcl_cb: ERROR unknown mode %d\n", this->tx_rx_mode)) + goto bad; + } + /* + * global session lock... there's only one! + */ + mcl_init_lock(&(this->session_lock)); + + /* + * addr initialization + */ + this->addr.reset(); /* call constructor manually */ + this->addr.set_port(5665); + this->mcast_if_addr = NULL; /* nothing by default */ + this->mcast_if_name = NULL; /* nothing by default */ + //this->rx.src_addr.reset(); /* call constructor manually */ + //this->rx.check_src_addr = false; + for (i = 0; i < MAX_MC_GROUP; i++) { + this->socket_tab[i].addr.reset(); /* call constructor man. */ + } + this->ttl = TTL; + this->demux_label = 0; // default TSI for filtering incoming pkts + /* + * choose a default tx profile. This will initialize at least the: + * single_layer_mode + * max_nb_layers + * congestion_control + * max_datagram_size + * payload_size (as a side effect of setting max_datagram_size) + * variables. + * the default tx profile can be changed in mcl_profile.h, and + * will anyway be overwritten by the FCAST/FLUTE application... + */ + this->congestion_control = INVALID_CC; /* let set_tx_profile choose */ + prof = DFLT_TX_PROFILE; + if (mcl_set_tx_profile(this, prof) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_alloc_mclcb: ERROR: mcl_set_tx_profile failed\n")) + mcl_exit(-1); + } + //this->rx.never_leave_base_layer = 1; + /* + * FEC initialization + */ + this->fec.initialize(); + + /* by default init nb_layer to 1; updated later in mcl_init_layer_nb */ + this->nb_layers = 1; /* only 1 tx layer to start... */ + this->mcl_max_group = MAX_MC_GROUP; + this->nb_tx = 1; /* by default single tx for each DU */ + + /* + * choose a packet scheduler and an object scheduler + */ +#if defined(LCT_SCHED1) + this->scheduler = MCL_SCHED_LCT1; +#else + Error, you must choose a scheduler! Define one in file mcl_profile.h. +#endif + /* by default mix everything */ + this->adu_scheduling = MCL_SCHED_MIXED_ORDER; + +#ifdef ANTICIPATED_TX_FOR_PUSH + this->anticipated_tx_for_push = true; +#endif + +#ifdef POSTPONE_FEC_DECODING + /* it is dangerous to set fec_decoding to 1 by default. Prefer 0! */ + this->postpone_fec_decoding = true; +#else + this->postpone_fec_decoding = false; +#endif + + this->tx_mem_cleanup_count = TX_MEM_CLEANUP_PERIOD; + this->stats_time_count = STATS_PERIOD; + + /* + * clear stats + */ + memset((void *)&this->stats, 0, sizeof(this->stats)); + + /* some more inits */ + this->findadu_cache = NULL; /* nothing by default */ + this->lastadu_cache = NULL; + this->ready_data = 0; +#ifdef METAOBJECT_USED + this->meta_obj_layer = new mcl_meta_object_layer(this); +#endif + this->sig_tab = NULL; + this->psig_next = NULL; + + // ok, return + return; + +bad: + PRINT_ERR((mcl_stderr, "mcl_cb::mcl_cb: failed\n")) + exit (-1); +} + + +/** + * Destructor. + * => See header file for more informations. + */ +mcl_cb::~mcl_cb () +{ + mclcb_tab[this->id] = NULL; + this->id = 0; + this->fully_initialized = false; +} + + +/** + * Free everything. + * => See header file for more informations. + */ +void +mcl_cb::free_everything () +{ +#ifdef DEBUG + mcl_cb *mclcb = this; // required by TRACELVL +#endif + + /* free ADUs and their buffers */ + this->tx.free_all_adu(this); +#if 0 + /* close all the opened sockets */ + this->ses_channel.sock_close(this); +#endif + + TRACELVL(5, (mcl_stdout, "-> mcl_free_mclcb:\n")) + /* + * close all the remaining sockets; + * especially required in case of a sender + */ + mcl_free_all_layers(this); + /* + * no sig service any more + */ + if (this->is_a_sender()) { + mcl_sig_close(this); + } + /* + * free all remaining data/adu/tx tab... + */ + if (this->is_a_sender()) { + INT32 lay; + txlay_t *tl; + for (lay = 0, tl = this->txlay_tab; lay < this->max_nb_layers; lay++, tl++) { + delete tl->tx_tab; + delete tl->tx_tab_high; + } + } + +#ifdef METAOBJECT_USED + /* close meta object mgmnt */ + delete this->meta_obj_layer; + this->meta_obj_layer = NULL; +#endif + + /* + * close congestion control services + */ +#ifdef RLC + if (this->is_a_receiver() && this->congestion_control == RLC_CC) { + rlc_end_session(this); + } +#endif +#ifdef FLIDS + if (this->is_a_receiver() && this->congestion_control == FLID_SL_CC) { + FLIDs_EndSession(this); + } +#endif + TRACELVL(5, (mcl_stdout, "<- mcl_free_mclcb: ok\n")) +} + + +/** + * + * => See header file for more informations. + */ +mcl_error_status +mcl_cb::set_verbosity (INT32 level) +{ + if (level < 0 || level > 6) { + PRINT_ERR((mcl_stderr, + "mcl_cb::set_verbosity: ERROR, level out of range (expected [0;6], got %d).\n", (int)level)) + return MCL_ERROR; + } + this->verbosity_level = (INT8)level; + return MCL_OK; +} + + +/** + * + * => See header file for more informations. + */ +mcl_error_status +mcl_cb::set_stats_level (INT32 level) +{ + if (level < 0 || level > 2) { + PRINT_ERR((mcl_stderr, "mcl_cb::set_stats_level: ERROR, level out of range (expected [0;2], got %d).\n", (int)level)) + return MCL_ERROR; + } + this->stats_level = (INT8)level; + return MCL_OK; +} + + +/** + * Finish the initialization of the session. + * => See header file for more informations. + */ +mcl_error_status +#ifdef SVSOA_RECV +mcl_cb::finish_session_init (int nb_lay) +#else +mcl_cb::finish_session_init () +#endif +{ +#ifdef DEBUG + mcl_cb *mclcb = this; // required by TRACELVL +#endif + INT32 mode = 0; /* init mode of sockets for each layer */ + + TRACELVL(5, (mcl_stdout, "-> mcl_cb::finish_session_init:\n")) + ASSERT((!this->fully_initialized)) + this->fully_initialized = true; + + /* + * perform socket initialization now... + */ + /* moved here from init_receiver which is called to late! */ + memset((void *)&this->rxlvl, 0, sizeof(this->rxlvl)); + /* + * set the init mode first... + */ + if (this->is_a_sender()) { + if (this->addr.is_multicast_addr()) { + mode = MODE_MCAST_TX; + } else { + mode = MODE_UNI_TX; + // in unicast, use a single layer! + this->max_nb_layers = 1; + this->single_layer_mode = true; + } + } else { + ASSERT(this->is_a_receiver()); + if (this->addr.is_multicast_addr()) { + mode = MODE_MCAST_RX; + } else { + mode = MODE_UNI_RX; + // in unicast, use a single layer! + this->max_nb_layers = 1; + this->single_layer_mode = true; + } + } + this->ucast_mcast_mode = mode; /* remember the ucast_mcast_mode */ + +#ifdef SVSOA_RECV + if (mcl_init_layer_nb(this, nb_lay) < 0) +#else + if (mcl_init_layer_nb(this) < 0) +#endif + { + PRINT_ERR((mcl_stderr, + "mcl_cb::finish_session_init: ERROR: mcl_init_layer_nb failed\n")) + mcl_exit(1); + } + /* + * ... then create the socket endpoints, + */ + //if (this->ses_channel.sock_init(this) != MCL_OK) + if (mcl_init_layer_sockets(this) != MCL_OK) { + PRINT_ERR((mcl_stderr, + "mcl_cb::finish_session_init: ERROR: socket initialization failed\n")) + mcl_exit(1); + } + /* + * ... then create/initialize everything else + */ + if (this->is_a_sender()) { + if (this->finish_init_as_a_sender() == MCL_ERROR) { + goto bad; + } + } else { + ASSERT(this->is_a_receiver()); + if (this->finish_init_as_a_receiver() == MCL_ERROR) { + goto bad; + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_cb::finish_session_init:\n")) + return MCL_OK; + +bad: + PRINT_ERR((mcl_stderr, "mcl_cb::finish_session_init: ERROR\n")) + mcl_exit(-1); + return MCL_ERROR; // avoid warning +} + + +/** + * Finishes the initialization of a sender. + * => See header file for more informations. + */ +mcl_error_status +mcl_cb::finish_init_as_a_sender () +{ + INT32 lay; + txlay_t *tl; + double sent_on_lower_layers; /* nb of packets per tick */ + /* already sent on lower tx layers */ +#ifdef DEBUG + mcl_cb *mclcb = this; // required by TRACELVL +#endif + double du_per_tick_scale[MAX_NB_TX_LAYERS]; // predefined tx rate scale + double tps; // ticks per second (also periodic + // timer frequency). + + TRACELVL(5, (mcl_stdout, "-> mcl_cb::finish_init_as_a_sender: id=%d\n", + this->get_id())) + /* required below but... */ + ASSERT((this->mcl_max_group == MAX_NB_TX_LAYERS)) + /* init the txlay array first... */ + memset((void *)this->txlay_tab, 0, sizeof(this->txlay_tab)); + + /* + * Calculate the transmission rate progression. + * Do not consider yet the rate on base layer... + */ +#define MAX_NB_OF_DUS_SENT_PER_TICK_PER_LAYER 20 + mcl_calc_tx_scale(&du_per_tick_scale[0], 0, + MAX_NB_OF_DUS_SENT_PER_TICK_PER_LAYER, + MAX_NB_TX_LAYERS); +#undef MAX_NB_OF_DUS_SENT_PER_TICK_PER_LAYER + /* + * initialize each txlay_t control block. + */ + sent_on_lower_layers = 0; + tps = mcl_periodic_timer::get_frequency(); + for (lay = 0, tl = this->txlay_tab; lay < this->max_nb_layers; lay++, tl++) { + tl->layer = lay; + /* number of ticks per second */ + /* (in order to send important data every IMPORTANT_DATA_FREQUENCY (microseconds) on each layer)*/ + /* timers between layers are shifted */ + tl->tx_high_flush = false; /* not needed by default */ + tl->tx_high_timer = (int) floor((double) (IMPORTANT_DATA_FREQUENCY / MCL_TIMER_PERIOD) / (this->max_nb_layers - lay)); + tl->tx_tab = new mcl_tx_tab(); + tl->tx_tab_high = new mcl_tx_tab(); + tl->socket = &(this->socket_tab[lay]); + tl->du_per_tick = (double)du_per_tick_scale[lay] * + this->rate_on_base_layer / tps; + tl->remaining_du_per_tick = 0.0; + TRACELVL(5, (mcl_stdout, + " mcl_cb::finish_init_as_a_sender: layer %d: du_per_tick_scale=%f, rate_on_base_layer=%f, tps=%f\n", + lay, du_per_tick_scale[lay], + this->rate_on_base_layer, tps)) + /* take advantage of data sent on lower layer */ + tl->cumul_du_per_tick = sent_on_lower_layers + tl->du_per_tick; + sent_on_lower_layers = tl->cumul_du_per_tick; + } + this->rx_thread = (mcl_thread_t)0; + if (this->get_verbosity() >= 1 || this->get_stats_level() >= 1) + mcl_print_tx_profile(this); + TRACELVL(5, (mcl_stdout, "<- mcl_cb::finish_init_as_a_sender: OK\n")) + return MCL_OK; +} + + +/** + * Finishes the initialization of a receiver. + * => See header file for more informations. + */ +mcl_error_status +mcl_cb::finish_init_as_a_receiver () +{ +#ifdef DEBUG + mcl_cb *mclcb = this; // required by TRACELVL +#endif + + TRACELVL(5, (mcl_stdout, + "-> mcl_cb::finish_init_as_a_receiver: id=%d\n", this->get_id())) + this->rxlvl.socket_head = this->socket_tab; + /* + * create the reception thread and lock + */ +#ifdef WIN32 + if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mcl_rx_thread, (void*)this, 0, (LPDWORD)&this->rx_thread) == NULL) { + perror("mcl_cb::finish_init_as_a_receiver: CreateThread"); + mcl_exit(1); + } +#elif defined(AIX) || defined(HPUX) || defined(IRIX) || defined(FREEBSD) || defined(SOLARIS) + { + pthread_attr_t attr; + size_t stack_size; + pthread_attr_init(&attr); + /* + * get the current stack size, and if lower than a given threshold, + * increase it. + */ + if (pthread_attr_getstacksize(&attr, &stack_size) != 0) { + perror("mcl_cb::finish_init_as_a_receiver: pthread_attr_getstacksize"); + mcl_exit(1); + } +#define MIN_STACK_SIZE 200 * 4096 + TRACELVL(5, (mcl_stdout, + " mcl_cb::finish_init_as_a_receiver: default stack size=%d, make sure it's no smaller than %d\n", MIN_STACK_SIZE)) + stack_size = max(stack_size, MIN_STACK_SIZE); + if (pthread_attr_setstacksize(&attr, stack_size) != 0) { + perror("mcl_cb::finish_init_as_a_receiver: pthread_attr_setstacksize"); + mcl_exit(1); + } + if ((pthread_create((pthread_t*)&this->rx_thread, &attr, + mcl_rx_thread, (void*)this)) != 0) { + perror("mcl_cb::finish_init_as_a_receiver: pthread_create"); + mcl_exit(1); + } + } +#else /* linux */ + if ((pthread_create((pthread_t*)&this->rx_thread, NULL, mcl_rx_thread, (void*)this)) != 0) { + perror("mcl_cb::finish_init_as_a_receiver: pthread_create"); + mcl_exit(1); + } +#endif + TRACELVL(5, (mcl_stdout, "<- mcl_cb::finish_init_as_a_receiver: OK\n")) + return MCL_OK; +} + + +/** + * + * => See header file for more informations. + */ +mcl_error_status +mcl_cb::set_max_datagram_size (INT32 sz) +{ + // sanity checks... + if (sz < MIN_ALC_HEADER_SIZE || sz > MAX_DATAGRAM_SIZE) { + PRINT_ERR((mcl_stderr, + "mcl_cb::set_max_datagram_size: size out of range (expected [%d;%d], got %d).\n", + MIN_ALC_HEADER_SIZE, MAX_DATAGRAM_SIZE, sz)) + return MCL_ERROR; + } + this->max_datagram_size = sz; + this->payload_size = this->max_datagram_size - MAX_ALC_HEADER_SIZE; + return MCL_OK; +} + + +/** + * + * => See header file for more informations. + */ +mcl_error_status +mcl_cb::set_payload_size (INT32 sz) +{ + // sanity checks... + if (sz < 1 || sz > MAX_PAYLOAD_SIZE) { + PRINT_ERR((mcl_stderr, + "mcl_cb::set_payload_size: size out of range (expected [1;%d], got %d).\n", + MAX_PAYLOAD_SIZE, sz)) + return MCL_ERROR; + } + if (sz >= this->max_datagram_size) { + PRINT_ERR((mcl_stderr, + "mcl_cb::set_payload_size: size %d cannot be larger than current max datagram size %d.\n", + sz, this->max_datagram_size)) + return MCL_ERROR; + } + this->payload_size = sz; + return MCL_OK; +} + + +#if 0 +/** + * Set the delivery mode. + * => See header file for more informations. + */ +mcl_error_status +mcl_cb::set_delivery_mode (mcl_cb *const mclcb, + mcl_delivery_mode mode) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_cb::set_delivery_mode: %s", + (mode == MCL_IMMEDIATE_DELIVERY) ? "IMMEDIATE_DELIVERY" : + "ORDERED_DELIVERY")) + this->delivery_mode = mode; + return MCL_OK; +} +#endif + + +/** + * Tx rate (in DUs per tick) calculations. + * => See header file for more informations. + */ +void +mcl_cb::mcl_calc_tx_scale (double *tab, + INT32 start, + double max, + INT32 nb_entries) +{ + double val; + double *last; // last valid entry in table to consider. + + ASSERT(tab && start >= 0 && nb_entries > 0); + last = &tab[nb_entries - 1]; +#ifdef RLC + if (this->congestion_control == RLC_CC) { + val = 1 << start; // value for base layer. + *tab++ = val; // tab[0] == tab[1] for a progression 1 1 2... + for (; tab <= last ; tab++) { + /* taking the min() leads to a less aggressive RLC, taking + * val follows the initial exponential scheme of RLC. */ + //*tab = val; + *tab =min(val, max); + val *= 2; + } + } +#endif +#ifdef FLIDS + if (this->congestion_control == FLID_SL_CC) { + val = pow(1.3, start); // value for base layer. + *tab++ = val; // tab[0] == tab[1] for a progression 1 1 2... + for (INT32 i = 1; tab <= last ; i++, tab++) { + *tab = (pow(1.3, i) - pow(1.3, i - 1)) * val; + } + } +#endif + if (this->congestion_control == NO_CC) { + *tab = 1.0; + } +} + diff --git a/src/alc/mcl_cb.h b/src/alc/mcl_cb.h new file mode 100644 index 0000000..978cb91 --- /dev/null +++ b/src/alc/mcl_cb.h @@ -0,0 +1,590 @@ +/* $Id: mcl_cb.h,v 1.32 2005/05/23 11:11:44 roca Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_CB_H /* { */ +#define MCL_CB_H + +#include "mcl_fec.h" /* cross-references */ + + +/** + * TRANSMISSION layer control block. + * One entry for each layer used by the sender. + */ +typedef struct txlay { + INT32 layer; /* tx layer (starts at 0) */ + double cumul_du_per_tick;/* target cumulative tx rate per tick */ + double du_per_tick; /* target tx rate per tick */ + double remaining_du_per_tick; /* number of DUs not sent */ + /* during previous tick, that should */ + /* have been sent though to match */ + /* target rate */ + class mcl_socket *socket; /* mcast group where data is sent */ + mcl_tx_tab *tx_tab; /* tx plannification table for */ + /* normal priority data */ + mcl_tx_tab *tx_tab_high; /* tx plannification table for high */ + /* priority data*/ + INT32 tx_high_timer; /* timer for high priority data, in + ticks. Tx is done when going to 0. */ + bool tx_high_flush; /* flush (i.e. send) the entire content + of tx_high immediatly. */ +#if 0 +//#ifdef RLC + char wait_sp; /* boolean: 1 = no tx on lay i before */ + /* sending the first SP on layer i-1 */ + char wait_after_sp_count;/* wait this # ticks after wait=0 */ +#endif +} txlay_t; + + +/** + * RECEPTION control block. + * Only one entry at the receiver, no matter the number of layers. + */ +typedef struct { + class mcl_socket *socket_head; /* head of mcast group tab */ + fd_set fds; /* set of fd, used by select */ + int nfds; /* highest-numbered fd + 1 */ + int n_fd; /* total nb of fd (ie sockets) */ + du_t *du_head; /* head of the orphan DU list */ +#ifdef FEC + du_t *dufec_head; /* head of the DU_FEC list */ +#endif +} rxlay_t; + + +/** + * Possible session modes. + */ +enum mcl_tx_rx_mode { + MCL_INVALID, + MCL_IS_A_SENDER_ONLY, + MCL_IS_A_RECEIVER_ONLY +}; + +/** + * Control Block Class for the MCL_ALC session. + * Contains all the variables, classes, member functions etc. required for + * a session. + */ +class mcl_cb { + +public: + + /****** Public Members ************************************************/ + /** + * Session control block constructor. + * Perform pre-initialization of the session. + * Called by mcl_open(). + * At completion, the session is NOT fully initialized, but + * sufficiently to enable most tasks to be performed (e.g all + * threads are created). + * @param mode determines if this is a sender or receiver + */ + mcl_cb (mcl_tx_rx_mode mode); + + /** Destructor */ + ~mcl_cb (); + + /** + * Finish the initialization of the session if not already done. + * This end of init is done only once. + * @param nb_lay number of layers + * @return Completion status (MCL_OK or MCL_ERROR). + */ +#ifdef SVSOA_RECV + mcl_error_status finish_session_init_if_needed (int nb_lay); +#else + mcl_error_status finish_session_init_if_needed (); +#endif + + /** + * True once the session if fully initialized. + * @return boolean + */ + bool is_fully_initialized (); + + /** + * Free everything. + * This is done at the very last stage, at the end of session close + * or abort, just before calling the destructor. + */ + void free_everything (); + + /** + * Returns the local MCL session id. + * The session identifier is set once, at session creation. + * @return session id + */ + INT32 get_id(); + + /** + * Get the tx/rx mode for this session. + * @return mode + */ + mcl_tx_rx_mode get_mode (); + + /** + * Is this session essentially a sending session. + * @return returns true when the MCL session has been opened + * in "w" and "wr" modes, false otherwise. + */ + bool is_a_sender (); + + /** + * Is this session essentially a receiving session. + * @return returns true when the MCL session has been opened + * in "r" and "rw" modes, false otherwise. + */ + bool is_a_receiver (); + + /** + * Set/unset the FLUTE compatibility mode. + * @param flute boolean: true in FLUTE compatibility mode + * (default: false) + */ + void set_flute_mode (bool onoff); + + /** + * True in FLUTE compatibility mode. + * @return true in FLUTE compatibility mode, false otherwise. + */ + bool is_flute_compatible (); + + /** + * Set the session lock. + * There is one lock per MCL session. Their total number is equal + * to the number of concurrent sessions. + */ + void lock (); + + /** + * Try to set the session lock. + * There is one lock per MCL session. Their total number is equal + * to the number of concurrent sessions. + * @return return EBUSY if not possible, 0 if ok + */ + INT32 trylock (); + + /** + * Release the session lock. + */ + void unlock (); + + /** + * Set the maximum datagram size (in bytes) and adjusts the payload + * size in consequence. + * A datagram includes the payload (if any) plus the ALC/LCT header. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_max_datagram_size (INT32 sz); + + /** + * Get the maximum datagram size (in bytes). + * A datagram includes the payload (if any) plus the ALC/LCT header. + * @return maximum datagram size in bytes + */ + INT32 get_max_datagram_size () const; + + /** + * Set the payload size (in bytes). + * Only the data payload of the ALC/LCT datagram is considered here. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_payload_size (INT32 sz); + + /** + * Get the payload size (in bytes). + * Only the data payload of the ALC/LCT datagram is considered here. + * Can be set independantly of the max_datagram_size but cannot + * be larger than this latter. + * @return payload size in bytes + */ + INT32 get_payload_size () const; + + /** + * Set the verbosity level. + * @param level + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_verbosity (INT32 level); + + /** + * Get the verbosity level. + * @return verbosity level + */ + INT32 get_verbosity (); + + /** + * Set the statistic level. + * @param level 0 means no stats at all, 2 means all statistics, + * 1 means only major statistics (e.g. at session end). + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_stats_level (INT32 level); + + /** + * Get the statistic level. + * @return statistic level + */ + INT32 get_stats_level (); + + + /****** Public Attributes *********************************************/ + /* + * All the classes/structs required by a session follow... + */ + /* + * SHARED BY SENDERS AND RECEIVERS + */ + class mcl_fsm fsm; + class mcl_periodic_proc periodic_proc; // For all periodic tasks + class mcl_fec fec; // FEC encoding/decoding class + // for all FEC flavors and the + // associated parameters + stats_t stats; // tx and rx statistics + //class mcl_ses_channel ses_channel; // session channel + //class mcl_alc_pkt_mgmt alc_pkt_mgmt; + + rlccb_t rlccb; // RLC control block + flids_cb_t flids_cb; // FLIDS control block + +#ifdef METAOBJECT_USED + class mcl_meta_object_layer *meta_obj_layer; // Meta object mgmt +#endif + + /* + * SENDER SPECIFIC + */ + class mcl_tx tx; // Transmission class + //class mcl_group_mgmt group_mgmt; + //class mcl_tx_ctrl tx_ctrl; // Performs control tasks + //class mcl_tx_window tx_window; // Store ADUs/DUs to send + class mcl_tx_flute tx_flute; // FLUTE specific tx functions + //class mcl_tx_storage tx_storage; // Virtual tx memory management + + /* + * RECEIVER SPECIFIC + */ + class mcl_rx rx; // Reception class + //class mcl_rx_thread rx_thread; // Reception thread + //class mcl_rx_ctrl rx_ctrl; // Performs control tasks + class mcl_rx_window rx_window; // Store received ADUs + class mcl_rx_flute rx_flute; // FLUTE specific rx functions + class mcl_rx_storage rx_storage; // Virtual rx memory management + + + /* + * And some additional public variables... + */ + + /* + * The number of layers, nb_layers, can vary in [1, max_nb_layers]. + * The maximum nb of layers, max_nb_layers, can vary in + * [1, MAX_NB_TX_LAYERS]. + * All table allocations are done with MAX_NB_TX_LAYERS. + */ + INT32 nb_layers; /** Current number of tx layers. */ + INT32 max_nb_layers; /** Maximum number of tx layers. */ + + /** Array of ctrl blocks for the sending side, one per layer. */ + txlay_t txlay_tab[MAX_NB_TX_LAYERS]; + + /* Control block for receiving side, only one, no matter the number + * of layers. */ + rxlay_t rxlvl; + +#ifdef WIN32 + BOOL test_cancel; /* used as a pthread_testcancel() alternative */ +#endif + + + /**********************************************************************/ + /*** Stuff below is here for historical reasons, will be removed... ***/ + + /* + * mode selection variables + */ + char ucast_mcast_mode; /* UNI_TX MCAST_TX UNI_RX MCAST_RX */ + bool single_layer_mode; /* optimize for single layer mode */ + mcl_congestion_control_scheme congestion_control; + /* congestion control mode: */ + /* NO_CC: no congestion control */ + /* RLC_CC: RLC */ + /* FLID_SL_CC: FLID-SL */ + /* Required for FLUTE interoperability tests */ + + /* + * time related variables + */ + int last_periodic_proc_tc;/* time_count for last do_periodic_proc call*/ + mcl_itime_t last_periodic_proc_it;/* idem with itime */ + int tx_mem_cleanup_count; /* tx memory cleanup function call period */ + int stats_time_count; /* for periodic stats print */ + + /* + * COMMON TX/RX VARIABLES + */ + int demux_label; /* LCT demux label, or tx session ID (TSI) */ + int cc_id; + char *mcast_if_name; /* name of mcast interface to use or NULL */ + class mcl_addr *mcast_if_addr;/* addr of mcast intf to use or NULL */ + class mcl_addr addr; /* unicast/mcast address and port on which */ + /* to rx (client) or tx (source). This is the */ + /* ALC session addr/port. With mcast, it uses */ + /* the ranges: */ + /* [addr; addr+max_nb_layers[ for addr, and */ + /* [port; port+max_nb_layers[ for port nb */ + UINT16 ttl; /* default TTL used with mcast */ + /* + * TX SPECIFIC VARIABLES + */ + char delivery_mode; /* which delivery mode? on-demand/push/... */ + double rate_on_base_layer; /* tx rate in packets/s on base layer */ + int nb_tx; /* # of desired tx for each DU */ + float remaining_tx_tick_nb;/* fractional tick_nb in do_periodic_proc */ + sig_tab_t *sig_tab; /* used by mcl_sig.c */ + int skip; /* used by mcl_sig.c */ + sig_tab_t *psig_next; /* used by mcl_sig.c */ + int mcl_sig_pending; /* is there any SIG msg pending ? counter */ + +#ifdef ANTICIPATED_TX_FOR_PUSH + char anticipated_tx_for_push; /* optimization for tx in PUSH mode */ +#endif +#ifdef VIRTUAL_TX_MEM + bool vtm_used; /* boolean: 1 to use virtual tx memory service*/ + bool vtm_initialized; /* boolean: 1 if vtm_cb is valid */ + vtm_cb_t vtm_cb; /* vtm control block for that session */ +#endif + int scheduler; /* shed to use for next UpdateTxPlanning call */ + int adu_scheduling; /* SEQUENTIAL, MIXED, PARTIALLY_MIXED, RANDOM */ + + /* + * RECEIVER SPECIFIC VARIABLES + */ + int ready_data; /* # completed ADU not yet returned to appli */ +#ifdef FEC + bool postpone_fec_decoding; /* decode during reception of at the end? */ + /* only valid with RSE, doesn't apply to LDPC */ +#endif + + /* + * various additional state/context + */ +#ifdef SIMUL_LOSSES + bool simul_losses_state; +#endif + int mcl_max_group; /* nb of mcast groups */ + class mcl_socket socket_tab[MAX_MC_GROUP]; /* array of mcast group contexts */ + mcl_thread_t rx_thread; /* rx thread idf */ + /* + * various working variables + */ + adu_t *findadu_cache; /* adu cache used by FindADU function */ + adu_t *lastadu_cache; /* adu cache to point to the last adu + * returned/or announced to appli */ + + +private: + /****** Private Members ***********************************************/ + /** + * Finish the initialization of the session. + * This function is called by once finish_session_init_if_needed() + * after that all the appropriate params have been set up with + * mcl_ctl(). + * It initializes everything (context, sockets, threads, etc.). + * @param nb_lay number of layers + * @return Completion status (MCL_OK or MCL_ERROR). + */ +#ifdef SVSOA_RECV + mcl_error_status finish_session_init (int nb_lay); +#else + mcl_error_status finish_session_init (); +#endif + + /** + * Finishes the initialization of a sender. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status finish_init_as_a_sender (); + + /** + * Finishes the initialization of a receiver. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status finish_init_as_a_receiver (); + + /* + * Tx rate (in DUs per tick) calculations. + * The exact transmission scale depends on the congestion control + * protocol used. + * With RLC: exponential scale (factor 2) up to "max" DUs/tick, and then + * linear scale of "max" DUs/tick + * With FLID-SL: exponential scale (factor 1.3). + * @param tab table where to store the result. + * @param start initial power of 2 (RLC) or 1.3 (FLIDS). + * @param max with RLC, maximum number of DUs per tick. + * @param tab_len number of entries in table to consider. + */ + void mcl_calc_tx_scale (double *tab, INT32 start, double max, INT32 tab_len); + + + /****** Private Attributes ********************************************/ + bool fully_initialized; // true when session is fully init'ed + // ie. after finish_session_init() + INT32 id; // MCL session identifier + mcl_tx_rx_mode tx_rx_mode; // is it a sender or a receiver? + bool flute_mode; // true in FLUTE compatibility mode, + // false otherwise + INT8 verbosity_level;// debug trace level + INT8 stats_level; // statistics level + mcl_mutex_t session_lock; // global session lock + + INT32 max_datagram_size; // max datagram size for tx and rx + INT32 payload_size; // default payload size for tx and rx + // the actual DU size used for a given ADU is + // kept in the adu->symbol_len, and may change + // for different ADUs (not yet supported!) +}; + + +/** + * Table containing the various control blocks of the sessions. + * There can be at most MCLCB_MAX_ID simultaneous sessions in an MCL-ALC + * instance. + */ +extern mcl_cb *mclcb_tab[MAX_NB_MCLCB]; + +/** One time initialization function for the mclcb table. */ +extern void mcl_init_mclcb_tab (void); + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +inline INT32 +mcl_cb::get_id() +{ + return this->id; +} + +inline mcl_tx_rx_mode +mcl_cb::get_mode () +{ + return this->tx_rx_mode; +} + +inline bool +mcl_cb::is_a_sender () +{ + //return (this->tx_rx_mode == MCL_IS_A_SENDER_ONLY || + // this->tx_rx_mode == MCL_IS_A_SENDER_AND_RECEIVER); + return (this->tx_rx_mode == MCL_IS_A_SENDER_ONLY); +} + +inline bool +mcl_cb::is_a_receiver () +{ + //return (this->tx_rx_mode == MCL_IS_A_RECEIVER_ONLY || + // this->tx_rx_mode == MCL_IS_A_RECEIVER_AND_SENDER); + return (this->tx_rx_mode == MCL_IS_A_RECEIVER_ONLY); +} + +inline void +mcl_cb::set_flute_mode (bool onoff) +{ + this->flute_mode = onoff; +} + +inline bool +mcl_cb::is_flute_compatible () +{ + return this->flute_mode; +} + +inline INT32 +mcl_cb::get_verbosity () +{ + return (INT32) this->verbosity_level; +} + +inline INT32 +mcl_cb::get_stats_level () +{ + return (INT32) this->stats_level; +} + +inline void +mcl_cb::lock () +{ + mcl_lock(&(this->session_lock)); +} + +inline INT32 +mcl_cb::trylock () +{ + return mcl_trylock(&(this->session_lock)); +} + +inline void +mcl_cb::unlock () +{ + mcl_unlock(&(this->session_lock)); +} + +inline mcl_error_status +#ifdef SVSOA_RECV +mcl_cb::finish_session_init_if_needed (int nb_lay) +#else +mcl_cb::finish_session_init_if_needed () +#endif +{ + if (this->fully_initialized) + return MCL_OK; + else +#ifdef SVSOA_RECV + return (this->finish_session_init(nb_lay)); +#else + return (this->finish_session_init()); +#endif +} + +inline bool +mcl_cb::is_fully_initialized () +{ + return this->fully_initialized; +} + +inline INT32 +mcl_cb::get_max_datagram_size () const +{ + return this->max_datagram_size; +} + +inline INT32 +mcl_cb::get_payload_size () const +{ + return this->payload_size; +} + +#endif /* } MCL_CB_H */ diff --git a/src/alc/mcl_data.h b/src/alc/mcl_data.h new file mode 100644 index 0000000..b563d74 --- /dev/null +++ b/src/alc/mcl_data.h @@ -0,0 +1,218 @@ +/* $Id: mcl_data.h,v 1.16 2005/04/07 15:51:38 moi Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_DATA_H /* { */ +#define MCL_DATA_H + +#include "mcl_vrmem.h" + +/****** data structures ******/ + + +/* + * ALC/LCT official terminology MCLv3 terminology + * ---------------------------- ----------------- + * transport object application data unit, or ADU (adu_t) + * block block (block_t) + * data (or source) symbol data unit, or DU (du_t, is_fec=0) + * parity (or redundant) symbol DU (du_t, is_fec=1) + */ + + +/* + * Distinguish between normal priority ADUs (e.g. data), and high + * priority ADUs (e.g. for control information, for FDT with FLUTE) + * that will be managed separately, on a distinct transmission + * plannification table. + */ +enum adu_priority_t { + ADU_NORMAL_PRIO = 0, + ADU_HIGH_PRIO +}; + + +/** + * Application Data Unit (ADU), AKA Transport Object. + * They are the unit of data submitted by the sending application + * in an mcl_send[to] call. + * The ADU boundaries are preserved and communicated to the receivers. + * Both sender and receivers keep a linked list of ADUs. + */ +typedef struct adu { + struct adu *prev, *next; + TOI_t seq; /* seq nb of this ADU (AKA TOI) */ + UINT32 len; /* number of bytes in this ADU */ + UINT32 padded_len; /* len with optional 0 padding */ + UINT32 FDT_instanceid; /* associated FDT instance ID if it */ + /* is an FDT (i.e. seq==0) (FLUTE) */ + /* blocking struct */ + UINT32 max_k; /* req. to calculate blocking struct */ + /* Warning: blocks may be shorter, this + * is not the actual max blk length */ + UINT32 max_n; /* req. to generate the FTI */ + struct mcl_blocking_struct blocking_struct; + /* blocking structure for this ADU: */ + /* gives nb and length of each block */ + struct block *block_head; /* first block of this ADU in list */ + //UINT32 block_nb; /* number of blocks in this ADU */ + UINT8 fec_encoding_id;/* FEC enc. id used for this ADU */ + UINT8 fec_instance_id;/* FEC inst. id used for this ADU */ + mcl_fec_scheme fec_scheme; /* FEC scheme used for this ADU */ + UINT16 symbol_len; /* full-sized symbol size in bytes */ + /* valid for all DUs of this ADU */ + class mcl_addr addr; /* ADU received from or destined to */ + bool addr_valid; /* boolean: true if the addr class is */ + /* valid, ie has been initialized */ + /* fields only used by the sender */ + char *data; /* ptr to data buffer */ + char in_txtab; /* boolean: 1 if there is at least one*/ + /* du waiting to be sent in txtab */ + adu_priority_t priority; /* 1 high importance (e.g. control) */ + /* 0 normal importance (default) */ +#if defined(VIRTUAL_TX_MEM) || defined(VIRTUAL_RX_MEM) + union { +#ifdef VIRTUAL_TX_MEM + /* field only used by the sender */ + struct vtmem_info vtm_info_u; /* adu/vtm correspondance */ +#endif +#if 0 +//#ifdef VIRTUAL_RX_MEM + /* field only used by the receiver */ + struct vrmem_info vrm_info_u; /* adu/vrm correspondance */ +#endif + } vxm; +#endif /* VIRTUAL_TX_MEM | VIRTUAL_RX_MEM */ + /* fields only used by the receivers */ + char ia_adu; /* boolean: 1 if implicitly announced */ + UINT32 recvd_src_data; /* number of bytes received or decoded*/ + /* Does not include parity symbols. */ + enum mcl_adu_rx_status rx_status; /* rx status: completed/delivered/..*/ +} adu_t; + + +/** + * Block. + * They are the result of the segmentation of ADUs into several + * blocks, each of size appropriate to the FEC codec in use. + * The algorithm used for this segmentation can be found in + * common/mcl_blocking_struct.cpp + */ +typedef struct block { + struct adu *adu; /* ADU to which this block belongs */ + TOI_t seq; /* block sequence number */ + UINT32 len; /* number of bytes in this block */ + struct du *du_head; /* first DU of this block in list */ + UINT32 k; /* nb of DUs for this block (k param) */ + UINT32 n; /* n parameter for this block */ +#ifdef FEC + struct du *fec_du_head; /* first FEC DU of this block in list */ + UINT32 fec_du_nb_in_list; /* nb of FEC DUs in this block */ + /* at a source, it's the n-k param. */ +#ifdef LDPC_FEC + UINT16 fec_key; /* LDGM/LDPC specific: random seed */ +#endif /* LDPC_FEC */ +#endif + /* fields only used by the receivers */ + UINT32 du_nb_in_list; /* nb of non-FEC DU recvd (!= k) */ + /* or decoded (in case of LDPC) */ + char rx_status; /* rx status (completed/decoded/..) */ +#ifdef LDPC_FEC + class LDPCFecSession *ldpc_ses; /* LDPC context, used by decoder */ + void **pkt_canvas; /* ptrs to pkt table, used by decoder */ + struct ldpc_callback_context* callback_ctxt; + /* carries context info required by */ + /* the LDPC callback function */ +#endif /* LDPC_FEC */ +} block_t; + +/* possible values of the du->rx_status field */ +#define BLK_STATUS_NIL 0 /* void status */ +#define BLK_STATUS_IN_PROGRESS 1 /* not yet ready */ +#define BLK_STATUS_COMPLETED 2 /* received all DUs from all blocks */ +#define BLK_STATUS_DECODED 3 /* COMPLETED and FEC decoding done */ + + +/** + * Data Unit (DU). + * They are the result of the FEC encoding of a block (i.e. ADU chunck) + * and identify a sequence of bytes. + * They can either contain plain data or redundant FEC data. + * They are the data payload of the packets sent. + * Used both by the sending and receiving sides. + */ +typedef struct du { + struct du *prev, *next; /* links used only by the receiver! */ + struct block *block; /* block to which this DU belongs */ + char *data; /* ptr to data in buffer */ + UINT32 seq; /* sequence number of this DU */ + UINT16 len; /* number of bytes in this DU */ +#ifdef FEC + bool is_fec; /* true if this is a FEC DU */ +#endif + /* rx specific field */ + class mcl_rx_pkt *pkt; /* object containing the packet recvd */ +#if 0 +#if defined(VIRTUAL_TX_MEM) || defined(VIRTUAL_RX_MEM) + struct vv { +#ifdef VIRTUAL_TX_MEM + /* field only used by the sender */ + struct vtmem_info vtm_info_u;/* adu/vtm correspondance */ +#endif +#ifdef VIRTUAL_RX_MEM + /* field only used by the receiver */ + struct vrmem_info vrm_info_u;/* adu/vrm correspondance */ +#endif + } vxm; +#endif /* VIRTUAL_TX_MEM | VIRTUAL_RX_MEM */ +#else +#ifdef VIRTUAL_RX_MEM + /* field only used by the receiver */ + struct vrmem_info vrm_info;/* adu/vrm correspondance */ +#endif +#endif +} du_t; + + +#if 0 +#if defined(VIRTUAL_TX_MEM) || defined(VIRTUAL_RX_MEM) +/* easy access for the adu_t and du_t union members */ +#define vtm_info vxm.vtm_info_u +#define vrm_info vxm.vrm_info_u +#endif /* VIRTUAL_TX_MEM | VIRTUAL_RX_MEM */ +#endif + + +/* + * Signaling list used by the sender to prepare ALC extension headers + */ +typedef struct sig_tab { + struct sig_tab *next; + int eh_type; /* EXT_CCI, ... SIG_NONEWADU, ... */ + char *buf; /* complementary info, or full ALC EH */ + int len; /* future ALC EH has this len (bytes) */ + int target_lvl; /* to send on this layer, any if -1 */ + int rem2send; /* nb of times it can still be sent */ + /*struct sockaddr *saddr;*/ /* destination, otherwise default lvl */ + class mcl_addr *saddr; /* destination, otherwise default lvl */ + int saddr_len; /* and associated len */ +} sig_tab_t; + +#endif /* } MCL_DATA_H */ diff --git a/src/alc/mcl_du.cpp b/src/alc/mcl_du.cpp new file mode 100644 index 0000000..84751e9 --- /dev/null +++ b/src/alc/mcl_du.cpp @@ -0,0 +1,146 @@ +/* $Id: mcl_du.cpp,v 1.5 2005/01/11 13:12:27 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "mcl_includes.h" + + +/* + * Create and init a new du_t struct. + */ +du_t* +CreateDU (mcl_cb *mclcb) +{ + du_t *ndu; + + if (!(ndu = (du_t*)calloc(1, sizeof(du_t)))) { + PRINT_ERR((mcl_stderr, "CreateDU: no memory")) + mcl_exit(-1); + } + return (ndu); +} + +/* + * Choose one of the two methods... + * BIN_TREE version is highly recommended with large block FEC codes, + * SEQ is sufficient for small block FEC codes + */ +//#define BINARY_TREE_LIST_OF_DUS +#define SEQUENTIAL_LIST_OF_DUS + +#ifdef BINARY_TREE_LIST_OF_DUS +TODO... +#elif defined(SEQUENTIAL_LIST_OF_DUS) + +/* + * last DU (i.e. with the highest seq nb) of the list. + */ +du_t* +LastDU (mcl_cb *mclcb, + du_t *list) +{ + if (list) + return (list->prev); + else + return NULL; +} + + +/* + * Insert the (single) du at its location (i.e. to comply + * with the increasing seq # property) in the list. + * WARNING: does not update the top level counter of DUs in list! + * Returns 1 if inserted, 0 if du was duplicated. + */ +int +InsertDU (mcl_cb *mclcb, + du_t *du, /* DU to add... */ + du_t **list) /* ... here */ +{ + du_t *pdu, *ndu; /* insert du between prev_du, next_du */ + + ASSERT((du && list)) + ASSERT(!du->next && !du->prev); /* single DU to add */ + TRACELVL(5, (mcl_stdout, "-> InsertDU: du=x%x\n", (int)du)) + pdu = LastDU(mclcb, *list); /* last DU in list, i.e. with highest seq nb */ + if (pdu == NULL) { + /* first DU in list */ + *list = du; + du->next = du->prev = du; + TRACELVL(5, (mcl_stdout, "<- InsertDU: first\n")) + return 1; + } + ndu = pdu->next; + /* + * find the proper location of du in the list to make + * sure seq numbers are always increasing + */ + while (du->seq < pdu->seq) { + ndu = pdu; + pdu = pdu->prev; + if (ndu == *list) { + /* we have cycled ! du is the new list head */ + *list = du; + break; + } + } + if (du->seq == pdu->seq) { + /* DU already received */ + TRACELVL(5, (mcl_stdout, "<- InsertDU: already rcvd\n")) + return 0; + } else { + /* new DU */ + pdu->next = du; + du->prev = pdu; + du->next = ndu; + ndu->prev = du; + TRACELVL(5, (mcl_stdout, "<- InsertDU: new\n")) + return 1; + } +} + +#endif /* XXX_LIST_OF_DUS */ + + +/* + * Each time a new FEC or data DU is received, call this function + * to check if we received enough DUs to build the complete block. + * Return 1 if ok, 0 otherwise. + */ +int +mcl_rx_enough_du (mcl_cb *mclcb, + block_t *blk) +{ + u_int nb; /* total nb of DUs received */ + +#ifdef FEC + nb = blk->du_nb_in_list + blk->fec_du_nb_in_list; +#else /* FEC */ + nb = blk->du_nb_in_list; +#endif /* FEC */ + TRACELVL(5, (mcl_stdout, " mcl_rx_enough_du: %d expected, %d rx\n", + blk->k, nb)) + if (nb >= blk->k) + return 1; + else + return 0; +} + diff --git a/src/alc/mcl_error.h b/src/alc/mcl_error.h new file mode 100644 index 0000000..bfc08e5 --- /dev/null +++ b/src/alc/mcl_error.h @@ -0,0 +1,35 @@ +/* $Id: mcl_error.h,v 1.4 2005/01/11 13:12:27 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_ERROR_H /* { */ +#define MCL_ERROR_H + +/* + * error codes returned by the various functions + */ + +#define ERR_CORRUPT_HDR -1000 +#define ERR_BAD_LAYER -1001 +#define TOO_MANY_LOSSES -1002 +#define ERR_OPT_UNKNOWN -1003 +#define ERR_BAD_TRIGGER -1004 + +#endif /* } MCL_ERROR_H */ diff --git a/src/alc/mcl_fec.cpp b/src/alc/mcl_fec.cpp new file mode 100644 index 0000000..922cd17 --- /dev/null +++ b/src/alc/mcl_fec.cpp @@ -0,0 +1,1327 @@ +/* $Id: mcl_fec.cpp,v 1.35 2005/05/17 12:36:57 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +#ifdef LDPC_FEC +/* a define specific to LDGM/LDPC */ +/*#define LEFT_DEGREE 10*/ +#define LEFT_DEGREE 3 +#endif + + +mcl_fec::mcl_fec () +{ + /* set everything to 0 */ + memset(this->max_k, 0, sizeof(this->max_k)); + memset(this->max_n, 0, sizeof(this->max_n)); + memset(this->cur_k, 0, sizeof(this->cur_k)); + memset(this->cur_n, 0, sizeof(this->cur_n)); + /* + * initialize everything + */ + this->initialize(); +} + + +mcl_fec::~mcl_fec () +{ +#ifdef DEBUG + memset(this->max_k, 0, sizeof(this->max_k)); + memset(this->max_n, 0, sizeof(this->max_n)); + memset(this->cur_k, 0, sizeof(this->cur_k)); + memset(this->cur_n, 0, sizeof(this->cur_n)); +#endif +} + + +/** + * Initializes the FEC class for a given FEC code. + * => See header file for more informations. + */ +void +mcl_fec::initialize () +{ + /* + * Initialize the fec class for each supported FEC code. + * The order is significant since the last call specifies the + * default FEC code. + */ + /* MCL_FEC_SCHEME_NULL case */ + // no fec codec used, so use default conservative values... + this->fec_codec = MCL_FEC_SCHEME_NULL; + this->max_k[MCL_FEC_SCHEME_NULL] = 255; + this->max_n[MCL_FEC_SCHEME_NULL] = 255; + this->cur_k[MCL_FEC_SCHEME_NULL] = 255; + this->cur_n[MCL_FEC_SCHEME_NULL] = 255; +#ifdef LDPC_FEC + /* MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1 case */ + this->fec_codec = MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1; + this->max_k[MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1] = LDPC_MAX_K; + this->max_n[MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1] = LDPC_MAX_N; + this->cur_k[MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1] = LDPC_DEFAULT_K; + this->cur_n[MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1] = LDPC_DEFAULT_N; + /* MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0 case */ + this->fec_codec = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0; + this->max_k[MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0] = LDPC_MAX_K; + this->max_n[MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0] = LDPC_MAX_N; + this->cur_k[MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0] = LDPC_DEFAULT_K; + this->cur_n[MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0] = LDPC_DEFAULT_N; +#endif +#ifdef RSE_FEC + /* MCL_FEC_SCHEME_RSE case */ + this->fec_codec = MCL_FEC_SCHEME_RSE_129_0; + ASSERT(RSE_MAX_K <= RSE_MAX_N); + ASSERT(RSE_MAX_N <= GF_SIZE); + this->max_k[MCL_FEC_SCHEME_RSE_129_0] = RSE_MAX_K; + this->max_n[MCL_FEC_SCHEME_RSE_129_0] = RSE_MAX_N; + this->cur_k[MCL_FEC_SCHEME_RSE_129_0] = RSE_DEFAULT_K; + this->cur_n[MCL_FEC_SCHEME_RSE_129_0] = RSE_DEFAULT_N; +#endif +} + + +/** + * Set the FEC code to be used. + * This function is sender specific (a receiver gets the FEC + * codec information info from the various incoming packet fields). + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::set_fec_code (mcl_cb *const mclcb, + const INT32 new_code) +{ + switch (new_code) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + this->fec_codec = MCL_FEC_SCHEME_RSE_129_0; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use RSE\n")) + return MCL_OK; +#endif + +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + this->fec_codec = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use LDPC-STAIRCASE\n")) + return MCL_OK; + + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + this->fec_codec = MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use LDPC-TRIANGLE\n")) + return MCL_OK; +#endif + + case MCL_FEC_SCHEME_NULL: + this->fec_codec = MCL_FEC_SCHEME_NULL; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use NO FEC\n")) + return MCL_OK; + + + default: + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_code: ERROR, code %d unknown\n", new_code)) + return MCL_ERROR; + } +} + + +/** + * Return the FEC code string corresponding to the current FEC codec + * used. + * WARNING: non re-entrant, the string is statically allocated... + * @return string with the name of the FEC code. + */ +char* +mcl_fec::get_fec_code_string () const +{ + switch (this->get_fec_code ()) { + case MCL_FEC_SCHEME_RSE_129_0: + return((char*)"Reed-Solomon FEC codec"); + case MCL_FEC_SCHEME_NULL: + return((char*)"NULL FEC codec"); + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + return((char*)"LDGM_STAIRCASE FEC codec"); + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + return((char*)"LDGM_TRIANGLE FEC codec"); + default: + return((char*)"ERROR, unknown FEC codec"); + } +} + + +/** + * Set the current FEC ratio, defined as cur_n/cur_k, and update + * either cur_n or cur_k, depending on the FEC codec. + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::set_fec_ratio (mcl_cb *const mclcb, + double new_fec_ratio) +{ + + if (new_fec_ratio < 1.0) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, bad new_fec_ratio (%f), must be >= 1.0\n", new_fec_ratio)) + return MCL_ERROR; + } + switch (this->fec_codec) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + return (this->set_fec_ratio_from_n(mclcb, new_fec_ratio)); +#endif + +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + return (this->set_fec_ratio_from_k(mclcb, new_fec_ratio)); + + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + return (this->set_fec_ratio_from_k(mclcb, new_fec_ratio)); +#endif + + case MCL_FEC_SCHEME_NULL: + return (this->set_fec_ratio_from_n(mclcb, new_fec_ratio)); + + default: + mcl_exit(-1); // impossible ! + return MCL_ERROR; // to avoid warning + } +} + + +mcl_error_status +mcl_fec::set_fec_ratio_from_n (mcl_cb *const mclcb, + double new_fec_ratio) +{ + + INT32 tmp_cur_k; // used with CODE_NULL and RSE + + tmp_cur_k = (INT32)((double)this->get_n() / new_fec_ratio); + if (tmp_cur_k < 1) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio_from_n: ERROR, new_fec_ratio %f too large\n", new_fec_ratio)) + return MCL_ERROR; + } + this->set_k(tmp_cur_k); + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::set_fec_ratio_from_n: max_k/n=(%d; %d), cur_k/n=(%d; %d), ratio=%f\n", + this->get_max_k(), this->get_max_n(), + this->get_k(), this->get_n(), this->get_fec_ratio())) + return MCL_OK; +} + + +mcl_error_status +mcl_fec::set_fec_ratio_from_k (mcl_cb *const mclcb, + double new_fec_ratio) +{ + INT32 tmp_cur_n; // used with LDGM and LDPC + + tmp_cur_n = (INT32)((double)this->get_k() * new_fec_ratio); + if (tmp_cur_n > this->get_max_n()) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, new_fec_ratio %f too large, would causes the cur_n (%d) to be larger than max_n (%d)\n", + new_fec_ratio, tmp_cur_n, this->get_max_n())) + return MCL_ERROR; + } + this->set_n(tmp_cur_n); + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::set_fec_ratio_from_n: max_k/n=(%d; %d), cur_k/n=(%d; %d), ratio=%f\n", + this->get_max_k(), this->get_max_n(), + this->get_k(), this->get_n(), this->get_fec_ratio())) + return MCL_OK; +} + + +/** + * Converts from FEC Encoding ID/FEC Instance ID to FEC scheme. + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::enc_inst_to_scheme (class mcl_cb *const mclcb, + UINT8 encid, + UINT8 instid, + mcl_fec_scheme *scheme) +{ + switch (encid) { + case FEC_ENCODING_ID_SMALL_SYSTEMATIC_FEC: +#ifdef RSE_FEC + if (instid != 0) { + goto bad; + } + *scheme = MCL_FEC_SCHEME_RSE_129_0; + break; +#endif + +#ifdef LDPC_FEC + case FEC_ENCODING_ID_PCM_FEC: + if (instid == 0) { + *scheme = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0; + } else if (instid == 1) { + *scheme = MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1; + } else { + goto bad; + } + break; +#endif + + case FEC_ENCODING_ID_NO_FEC: + if (instid != 0) { + goto bad; + } + *scheme = MCL_FEC_SCHEME_NULL; + break; + + + default: + goto bad; + } + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::enc_inst_to_scheme: FEC Enc ID/Inst ID=(%d/%d), scheme is %d\n", + encid, instid, (INT32)*scheme)) + return MCL_OK; + +bad: + PRINT_ERR((mcl_stderr, + "mcl_fec::enc_inst_to_scheme: ERROR, unknown FEC Encoding ID/FEC Instance ID (%d, %d)\n", + encid, instid)) + return MCL_ERROR; +} + + +/** + * Converts from FEC scheme to FEC Encoding ID/FEC Instance ID. + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::scheme_to_enc_inst (class mcl_cb *const mclcb, + mcl_fec_scheme scheme, + UINT8 *encid, + UINT8 *instid) +{ + switch (scheme) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + *encid = FEC_ENCODING_ID_SMALL_SYSTEMATIC_FEC; + *instid = 0; + break; +#endif + +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + *encid = FEC_ENCODING_ID_PCM_FEC; + *instid = 0; + break; + + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + *encid = FEC_ENCODING_ID_PCM_FEC; + *instid = 1; + break; +#endif + + case MCL_FEC_SCHEME_NULL: + *encid = FEC_ENCODING_ID_NO_FEC; + *instid = 0; + break; + + default: + PRINT_ERR((mcl_stderr, + "mcl_fec:: enc_inst_to_scheme: ERROR, unknown scheme (%d)\n", + scheme)) + return MCL_ERROR; + } + return MCL_OK; +} + + +/** + * Return the number of FEC packets that can still be created for this + * block. + * => See header file for more informations. + */ +INT32 +mcl_fec::get_rem_nb_fec_pkts_to_create (mcl_cb *const mclcb, + block_t *blk) +{ +#ifdef FEC + return (this->get_n() - blk->k - blk->fec_du_nb_in_list); +#else + return 0; +#endif +} + + +/** + * Determine the number of FEC packets required for this block. + * Depends on the block size (k) and the kind of scheduling used + * for this session. + * => See header file for more informations. + */ +INT32 +mcl_fec::compute_n_for_this_block (mcl_cb *const mclcb, + INT32 k) +{ + ASSERT(k > 0); + ASSERT(k <= this->get_max_k()); + switch(mclcb->scheduler) { + case MCL_SCHED_LCT1: + { + int n; + //n = min ((int)floor(this->get_fec_ratio() * k), this->get_n()); + if (k == this->get_k()) { + /* + * full-sized block; + * ignore the FEC ratio here since it is already + * considered in get_n()) + */ + n = this->get_n(); + } else { + /* + * non full-sized block; + * consider the FEC ratio here + */ + n = (int)floor((double)this->get_fec_ratio() * (double)k); + } + TRACELVL(4, (mcl_stdout, + " compute_n_for_this_block: SCHED1, k=%d n=%d, %d FEC DUs, cur_k=%d, cur_n=%d\n", + k, n, n - k, this->get_k(), this->get_n())) + return(n); + } + default: + PRINT_ERR((mcl_stderr, + "mcl_fec::compute_n_for_this_block: ERROR, unknown scheduler\n")) + mcl_exit(-1); + return(1); // avoid warnings! + } +} + +#ifdef FEC +/** + * Encode the block and create the appropriate number of new FEC packets. + * => See header file for more informations. + */ +INT32 +mcl_fec::encode (mcl_cb *const mclcb, + block_t *blk) +{ + INT32 k; // effective # source DUs for this block + // FEC DU seq nbs follow source DUs + INT32 n; // total of n (FEC + source) DUs + INT32 fec_seq; // FEC packet sequence number + UINT32 du_len; + UINT32 last_du_len; + INT32 i; +#ifdef RSE_FEC + void *code = NULL; /* ptr to the RSE FEC object */ +#endif +#ifdef LDPC_FEC + LDPCFecSession *ldpc_ses = NULL; /* ptr to the FEC session class */ +#endif + du_t *fec_du; + char *fec_data; + void **pkt_canvas = NULL; /* table of ptrs to packets */ + /* With RSE, a table of k entries is enough, */ + /* with LDGM, a table of k entries is enough, */ + /* BUT with LDPC the table must have n entries*/ + du_t *du; + + if (this->fec_codec == MCL_FEC_SCHEME_NULL) { + TRACELVL(5, (mcl_stdout, + " mcl_fec::encode(NULL): useless, no FEC mode, return 0\n")) + return 0; + } + ASSERT(blk); + /* + * Sanity checks... + */ + k = blk->k; + ASSERT(k <= this->get_k()); + n = this->compute_n_for_this_block(mclcb, k); + ASSERT(n <= this->get_n()); + /* + * see if some FEC is still required + */ + if (n == k) { + TRACELVL(5, (mcl_stdout, + " mcl_fec::encode(NULL): useless, no FEC required, return 0\n")) + return 0; + } + /* + * compute the size of a full-sized DU and of the last DU + * which may be shorter + */ + //du_len = mclcb->get_payload_size(); + //du_len = mclcb->payload_size; + du_len = blk->adu->symbol_len; + last_du_len = (k > 1) ? blk->len % du_len : blk->len; + if (last_du_len == 0) + last_du_len = du_len; /* multiple */ + /* + * create all the required FEC DUs for this block + */ + switch (this->fec_codec) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + TRACELVL(5, (mcl_stdout, "-> mcl_fec::encode(RSE): blk seq=%d, k=%d, n=%d\n", blk->seq, k, n)) + if (!(code = fec_new(k,n))) { + goto no_memory; + } + break; +#endif +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + TRACELVL(5, (mcl_stdout, "-> mcl_fec::encode(LDPC): blk seq=%d, k=%d, n=%d, key=%d\n", blk->seq, k, n, blk->fec_key)) + ldpc_ses = new LDPCFecSession; + /* + * NB: fec_key initialization moved to ADU segmentation + * function in order to do it immediately, at ADU submission. + * It's important if there's a risk the FTI be transmitted + * before mclcb->fec.encode() is called! + * Besides the key must be the same for all blocks because + * of FTI limitations (only one value carried). + */ + if (ldpc_ses->InitSession(k, n-k, du_len, FLAG_CODER, + min(LEFT_DEGREE, n-k), + blk->fec_key, + TypeSTAIRS) == LDPC_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::encode(LDPC): ERROR, LDPCFecSession::InitSession failed\n")) + mcl_exit(-1); + } +#ifdef DEBUG + if (mclcb->get_verbosity() >= 2) { + ldpc_ses->SetVerbosity(1); + } +#endif + break; +#endif + default: + mcl_exit(-1); // NULL FEC not possible here + } + +#ifdef VIRTUAL_TX_MEM + if (mclcb->vtm_used) { + /* + * first, move data in memory; assumes VTMEM cache is large + * enough to contain the whole block data! + */ + /* XXX: not efficient, must get it from disk... */ + char *data; + for (i = 0; i < k; i++) { + data = mcl_vtm_get_data(mclcb, &(blk->du_head[i])); + ASSERT(data); + /* check that VTMEM cache is sufficiently large */ + if (blk->du_head[i].data == NULL) { + PRINT_ERR((mcl_stderr, "mcl_fec::encode: ERROR, Virtual Tx Memory cache too small\n")) + mcl_exit(-1); + } + } + } +#endif /* VIRTUAL_TX_MEM */ + + /* + * no data copy except for the last du which may be shorter. + * for the last DU, (c)allocate a block, of "du_len" size, and copy + * the "last_du_len" bytes in it. + */ + switch (this->fec_codec) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + if (!(pkt_canvas = (void**)malloc(k * sizeof(char*)))) { + goto no_memory; + } + break; +#endif +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + if (!(pkt_canvas = (void**)calloc(n, sizeof(char*)))) { + goto no_memory; + } + break; +#endif + default: + mcl_exit(-1); // NULL FEC not possible here + } + for (i = 0, du = blk->du_head; i < k - 1; i++, du++) { + pkt_canvas[i] = (void*)(du->data); + } + if (!(pkt_canvas[k-1] = (void*)calloc(1, du_len))) { + goto no_memory; + } + ASSERT(du->seq == (UINT32)k-1); + ASSERT(du->len == last_du_len); + memcpy(pkt_canvas[k-1], du->data, last_du_len); + /* + * do it simply: allocate a tab of FEC du_t structs + * rather than a linked list! + * XXX: cannot be used if additional FEC packets are created later... + */ + ASSERT(blk->fec_du_head == NULL); + if (!(blk->fec_du_head = (du_t*)calloc(n-k, sizeof(du_t)))) { + goto no_memory; + } + blk->fec_du_nb_in_list = n-k; /* n-k fec added */ + + /* + * now create the n-k FEC DUs + */ + for (fec_seq = k, fec_du = blk->fec_du_head; + fec_seq < n; + fec_seq++, fec_du++) { + if (!(fec_data = (char *)malloc(du_len))) { + goto no_memory; + } + switch (this->fec_codec) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + fec_encode(code, pkt_canvas, fec_data, fec_seq, du_len); + break; +#endif +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + //TRACE((mcl_stdout, + // "mcl_fec::encode: fec_seq=%d, fec_data=x%x, du_len=%d\n", + // fec_seq, (int)fec_data, du_len)) + ldpc_ses->BuildFecPacket(pkt_canvas, fec_seq - k, (void*)fec_data); + // store packet in the canvas + pkt_canvas[fec_seq] = (void*)(fec_data); + break; +#endif + default: + mcl_exit(-1); // NULL FEC not possible here + } + //fec_du = new mcl_du; + // fec_du->next = fec_du->prev = NULL; + fec_du->block = blk; + fec_du->data = fec_data; + fec_du->seq = fec_seq; + fec_du->len = du_len; + fec_du->is_fec = true; + //fec_du->pkt = NULL; // this is how a tx DU is distinguished + // from a rx DU! + //fec_du->set_next(NULL); + //fec_du->set_prev(NULL); +#if 0 + /* + * Use a linked list of FEC DUs rather than a single tab as + * with data DUs on the sending side! + */ + if (blk->insert_in_fec_du_list(mclcb, fec_du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_fec::encode: ERROR, insert_in_fec_du_list() failed\n")) + mcl_exit(-1); + } +#endif +#ifdef VIRTUAL_TX_MEM + fec_du->vtm_info.du_in_seq_in_txtab = 1; /* by default */ + if (mcl_vtm_can_store_in_vtm(mclcb, (int)du_len)) { + /* + * use the VTMEM service to register data + */ + if (mcl_vtm_store_data(mclcb, NULL, fec_du, fec_data, + (INT32)du_len, 0)) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: Virtual Tx Memory service failed\n")) + mcl_exit(-1); + } + free(fec_data); /* no longer needed */ + } else { +#endif /* VIRTUAL_TX_MEM */ + /* + * store in physical memory + */ + fec_du->data = fec_data; +#ifdef VIRTUAL_TX_MEM + if (mclcb->vtm_used) { + /* remember it is kept in physical memory */ + mcl_vtm_register_in_ptm(mclcb, NULL, fec_du, + (int)du_len); + } + } +#endif /* VIRTUAL_TX_MEM */ + + TRACELVL(5, (mcl_stdout, + " mcl_fec::encode: created FEC seq=%d, len=%d, buf=x%x\n", + (INT32)fec_du->seq, (INT32)fec_du->len, + (INT32)fec_du->data)) + } + free(pkt_canvas[k-1]); + free(pkt_canvas); + switch (this->fec_codec) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + fec_free(code); + break; +#endif +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + ldpc_ses->EndSession(); + delete ldpc_ses; + break; +#endif + default: + mcl_exit(-1); // NULL FEC not possible here + } + TRACELVL(5, (mcl_stdout, "<- mcl_fec::encode: %d fec_du\n", n - k)) + return (n - k); + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_fec::encode: ERROR, no memory\n")) + mcl_exit(-1); + return -1; // useless but avoids a warning +} +#endif /* FEC */ + + + +#ifdef RSE_FEC +/** + * Decode the block immediately. + * This function is for Reed-Solomon and similar FEC codes. + * => See header file for more informations. + */ +INT32 +mcl_fec::decode (mcl_cb *const mclcb, + block_t *blk) +{ + INT32 k; + INT32 n; + UINT32 du_len; /* full-sized DU length */ + UINT32 last_du_len; /* last DU (true) length */ + INT32 i; + u_char **dst; /* put rx data or fec here... */ + INT32 rx_index[GF_SIZE]; /* ... and their seq# here */ + INT32 idx; /* index in dst[] and rx_index[] tabs */ + UINT32 rem; /* remaining nb of DUs */ + void *code; + du_t *du; + du_t *ndu; + UINT32 seq; /* next seq number expected */ + mcl_rx_pkt *pkt; /* used for data DUs created during decoding */ + u_char *buf; /* buffer where data/FEC DU data is copied */ + INT32 off; /* offset */ + + ASSERT(blk); + TRACELVL(5, (mcl_stdout, "-> mcl_fec::decode(RSE): block seq=%d\n",blk->seq)) + /* make sure RSE is registered... required by some FEC functions + * like compute_n_for_this_block() */ + //this->set_fec_code (mclcb, MCL_FEC_SCHEME_RSE_129_0); + this->fec_codec = MCL_FEC_SCHEME_RSE_129_0; + /* + * check that FEC decode is indeed needed (i.e. that + * we need at least one FEC DU) + */ + k = blk->k; + n = blk->n; + ASSERT(n >= k); + //if (blk->get_du_nb_in_list() >= k) + if ((int)blk->du_nb_in_list >= k) { + //blk->set_rx_status(BLK_STATUS_DECODED); + blk->rx_status = BLK_STATUS_DECODED; + TRACELVL(5, (mcl_stdout, + " mcl_fec::decode(RSE): decoding not needed\n")) + /*TRACELVL(5, ("mcl_fec::decode(RSE): k=%d, du_in_list=%d, fec_in_list=%d\n", k, blk->get_du_nb_in_list(), blk->get_fec_du_nb_in_list()))*/ + goto free_fec_du; + } + /* + * compute the size of a full-sized DU and of the last DU + * which may be shorter + */ + //du_len = mclcb->get_payload_size(); + du_len = blk->adu->symbol_len; + last_du_len = (k > 1) ? blk->len % du_len : blk->len; + if (last_du_len == 0) + last_du_len = du_len; /* multiple */ + /* + * copy data and fec in dst buffer array first + * NB: this is required by the current FEC codec which modifies + * the dst buffers!!! + */ + if (!(dst = (u_char **) malloc(k * sizeof(u_char *)))) { + goto no_memory; + } + /* alloc a single large buf, where to copy all data/FEC DU data... */ + if (!(buf = (u_char *) malloc(k * du_len))) { + goto no_memory; + } + /* and remember the location of each DU buffer */ + for (i = 0, off = 0; i < k; i++, off += du_len) { + dst[i] = buf + off; + } + idx = 0; /* index in rx_index[] */ + /* + * copy data DU to the dst array first + */ + //for (rem = blk->get_du_nb_in_list(), du = blk->get_du_head(); + // rem > 0; idx++, rem--, du = du->get_next()) + for (rem = blk->du_nb_in_list, du = blk->du_head; + rem > 0; idx++, rem--, du = du->next) { + ASSERT(du); + /* WARNING: if the following test failed, you probably forgot */ + /* to set the same tx_profile at the source AND receiver */ + if (du->len != du_len && du->len != last_du_len) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(RSE): ERROR: bad packet length (expected %d or %d, got %d)\nCheck transmission profiles at sender/receiver\n", + du_len, last_du_len, du->len)) + goto fatal_error; + } + if (idx >= k) + break; /* security, eg. if there are more than k DUs */ + if (mclcb->rx_storage.get_data(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(RSE): ERROR: rx_storage.get_data() failed\n")) + goto fatal_error; + } + memcpy(dst[idx], du->data, du->len); + if (du->len < du_len) { + /* non full-sized DU, so reset the remaining bytes */ + memset(dst[idx] + du->len, 0, du_len - du->len); + } + rx_index[idx] = du->seq; +#if 0 + PRINT_OUT((mcl_stdout, "mcl_fec::decode(RSE): copy DATA du->seq=%d in dst[%d], rx_index[%d]=%d\n", + du->seq, idx, idx, rx_index[idx])) +#endif + } + /* + * copy FEC DUs to the dst array now + */ + //for (rem = blk->get_fec_du_nb_in_list(), du = blk->get_fec_du_head(); + // rem > 0; idx++, rem--, du = du->get_next()) + for (rem = blk->fec_du_nb_in_list, du = blk->fec_du_head; + rem > 0; idx++, rem--, du = du->next) { + ASSERT(du); + if (du->len != du_len) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(RSE): ERROR: bad FEC packet length (expected %d or %d, got %d)\nCheck transmission profiles at sender/receiver\n", + du_len, last_du_len, du->len)) + goto fatal_error; + } + ASSERT(du->len == du_len); + if (idx >= k) { + /* security, if there are more than k data+FEC DUs */ + break; + } + if (mclcb->rx_storage.get_data(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(RSE): ERROR: rx_storage.get_data() failed\n")) + goto fatal_error; + } + memcpy(dst[idx], du->data, du->len); + /* rx_index[idx] = du->seq + k; */ + rx_index[idx] = du->seq; +#if 0 + PRINT_OUT((mcl_stdout, "mcl_fec::decode(RSE): copy FEC du->seq=%d in dst[%d], rx_index[%d]=%d\n", + du->seq, idx, idx, rx_index[idx])) +#endif + } + /* + * now decode + * NB: all the dst packets must be du_len long + */ + code = fec_new(k, n); + if (fec_decode(code, (void**)dst, rx_index, du_len)) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode(RSE): ERROR, fec_decode failed\n")) + TRACELVL(5, (mcl_stdout, "<- mcl_fec::decode(RSE): ERROR, calculated k/n=(%d, %d), cur_k/cur_n=(%d, %d)\n", k, n, this->get_k(), this->get_n())) + fec_free(code); + return -1; + } + fec_free(code); + + /* + * now update the block with the rx or reconstructed DUs + */ + //for (rem = blk->k, seq = 0, du = blk->get_du_head(); + // rem > 0; rem--, seq++, du = du->get_next()) + for (rem = blk->k, seq = 0, du = blk->du_head; + rem > 0; rem--, seq++, du = du->next) { + if (du && du->seq == seq) { + /* nothing to do, DU already received */ + continue; + } + /* + * else copy it from the FEC decoded matrix + */ + //du = new mcl_du; + du = CreateDU(mclcb); + /* next = prev = NULL */ + du->block = blk; + du->seq = seq; + if (rem > 1) + du->len = du_len; + else + du->len = last_du_len; + du->is_fec = false; + //du->set_next(NULL); + //du->set_prev(NULL); + /* + * copy/store the decoded data now + */ + pkt = new mcl_rx_pkt (du->len); + ASSERT(pkt); + pkt->pkt_len = du->len; + du->pkt = pkt; + du->data = pkt->get_buf(); + memcpy(du->data, dst[seq], du->len); + if (mclcb->rx_storage.store_data(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(RSE): ERROR: rx_storage.store_data() failed\n")) + goto fatal_error; + } + /* + * and insert it in the data DU list + */ + //if (blk->insert_in_du_list(mclcb, du) == MCL_ERROR) { + // PRINT_ERR((mcl_stderr, "mcl_fec::decode(RSE): ERROR, insert_in_fec_du_list() failed\n")) + // mcl_exit(-1); + //} + InsertDU(mclcb, du, &(blk->du_head)); + blk->du_nb_in_list++; + blk->adu->recvd_src_data += du->len; + TRACELVL(5, (mcl_stdout, + " mcl_fec::decode(RSE): created DU seq=%d from dst[%d], len=%d, du->data=x%x\n", + du->seq, seq, du->len, (int)du->data)) + } + //blk->set_rx_status(BLK_STATUS_DECODED); + blk->rx_status = BLK_STATUS_DECODED; + /* + * free the dst[] array and fec DU list now + */ + /* + * Warning: the fec_decode function can shuffle dst[] entries, so + * the new dst[0] entry may not point to buffer allocated previously! + */ + free(buf); + free(dst); +free_fec_du: + //blk->remove_and_free_all_fec_dus(mclcb); + for (rem = blk->fec_du_nb_in_list, du = blk->fec_du_head; rem > 0; + rem--, du = ndu) { + ndu = du->next; + if (mclcb->rx_storage.free_data(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(RSE): ERROR: rx_storage.free_data() failed\n")) + goto fatal_error; + } + free(du); + } + blk->fec_du_head = NULL; + blk->fec_du_nb_in_list = 0; + + TRACELVL(5, (mcl_stdout, "<- mcl_fec::decode(RSE): ok\n")) + return 0; + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_fec::decode(RSE): ERROR, no memory")) + mcl_exit(-1); + +fatal_error: + PRINT_ERR((mcl_stderr, "mcl_fec::decode(RSE): ERROR")) + mcl_exit(-1); + return -1; /* unreachable; avoid a compiler warning */ +} +#endif /* RSE_FEC */ + + +#ifdef LDPC_FEC +/** + * Progress in the block decoding with the given packet. + * This function is for LDPC and similar FEC codes who use an + * iterative decoding approach. + * => See header file for more informations. + */ +INT32 +mcl_fec::decode (mcl_cb *const mclcb, + du_t *rx_du) +{ + block_t *blk; + UINT32 k; + UINT32 n; + UINT32 du_len; // full-sized DU length + //UINT32 last_du_len; // last DU (true) length + //INT32 i; + INT32 rem; // remaining nb of DUs in iter loop + du_t *du; // current DU in DU iteration loop + du_t *ndu; // next DU in the DU iteration loop + + ASSERT(rx_du); + blk = rx_du->block; + ASSERT(blk); + TRACELVL(5, (mcl_stdout, + "-> mcl_fec::decode(LDPC-*): du->seq=%d, block seq=%d\n", + rx_du->seq, blk->seq)) + /* make sure LDGM* is registered... required by some FEC functions + * like compute_n_for_this_block() */ + //this->set_fec_code (mclcb, MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0); + //this->fec_codec = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0; + ASSERT((this->fec_codec = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0) || + (this->fec_codec == MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1)); + /* + * check that FEC decode is indeed needed (i.e. that + * we need at least one FEC DU) + */ + k = blk->k; + n = blk->n; + ASSERT(n >= k); + if (k == n && blk->du_nb_in_list >= k) { + /* + * decoding is over for this block which in fact does not + * use FEC encoding (no parity symbol, k == n). + */ + //blk->set_rx_status(BLK_STATUS_DECODED); + blk->rx_status = BLK_STATUS_DECODED; + ASSERT(blk->ldpc_ses == NULL); + ASSERT(blk->pkt_canvas == NULL); + ASSERT(blk->callback_ctxt == NULL); + ASSERT(blk->fec_du_nb_in_list == 0); + ASSERT(blk->fec_du_head == NULL); + TRACELVL(5, (mcl_stdout, "<- mcl_fec::decode(LDPC-*): ok but FEC not used\n")) + return 1; + } + /* + * LDPC initialization if applicable + */ + if (blk->ldpc_ses == NULL) { + /* + * first call to this LDPC decoding function for this + * block, so create the LDCP context and packet table. + */ + du_len=blk->adu->symbol_len; + ASSERT(blk->pkt_canvas == NULL); + blk->ldpc_ses = new LDPCFecSession; + /* + * XXX: the initial seed to rand() must be random! Change it + * and give the info to the receiver... + */ + if (blk->ldpc_ses->InitSession(k, n-k, du_len, FLAG_DECODER, + min(LEFT_DEGREE, n-k), + blk->fec_key, + TypeSTAIRS) == LDPC_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(LDPC-*): ERROR, LDPCFecSession::InitSession failed\n")) + mcl_exit(-1); + } +#ifdef DEBUG + if (mclcb->get_verbosity() >= 2) { + blk->ldpc_ses->SetVerbosity(1); + } +#endif + if (!(blk->callback_ctxt = (ldpc_callback_context_t*)malloc(sizeof(ldpc_callback_context_t)))) { + goto no_memory; + } + blk->callback_ctxt->mclcb = mclcb; + blk->callback_ctxt->block = blk; + if (blk->ldpc_ses->SetCallbackFunctions( + this->decoded_pkt_callback, + this->alloc_tmp_buffer_callback, + this->get_data_callback, + this->get_data_ptr_only_callback, + this->store_data_callback, + this->free_pkt_callback, + blk->callback_ctxt) + == LDPC_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(LDPC-*): ERROR, LDPCFecSession::SetCallbackFunctions failed\n")) + mcl_exit(-1); + } + if (!(blk->pkt_canvas = (void **)calloc(n, sizeof(void*)))) { + goto no_memory; + } + + } + /* + * now decode... + */ +#ifdef VIRTUAL_RX_MEM + if (blk->ldpc_ses->DecodeFecStep(blk->pkt_canvas, rx_du, rx_du->seq) + == LDPC_ERROR) +#else + if (blk->ldpc_ses->DecodeFecStep(blk->pkt_canvas, rx_du->data, rx_du->seq) + == LDPC_ERROR) +#endif + { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(LDPC-*): ERROR, DecodeFecStep failed\n")) + mcl_exit(-1); + } + /* + * check if decoding is complete... + */ + if (blk->du_nb_in_list >= k && + blk->ldpc_ses->IsDecodingComplete(blk->pkt_canvas)) { + /* + * decoding is over for this block, free all FEC DUs now... + */ + //blk->set_rx_status(BLK_STATUS_DECODED); + blk->rx_status = BLK_STATUS_DECODED; + blk->ldpc_ses->EndSession(); + delete blk->ldpc_ses; + blk->ldpc_ses = NULL; + ASSERT(blk->pkt_canvas); + free(blk->pkt_canvas); + blk->pkt_canvas = NULL; + ASSERT(blk->callback_ctxt); + free(blk->callback_ctxt); + blk->callback_ctxt = NULL; + /* free all the FEC DUs now */ + //blk->remove_and_free_all_fec_dus(mclcb); + for (rem = blk->fec_du_nb_in_list, du = blk->fec_du_head; + rem > 0; + rem--, du = ndu) { + ndu = du->next; + ASSERT(du->is_fec); + if (mclcb->rx_storage.free_data(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(RSE): ERROR: rx_storage.free_data() failed\n")) + goto fatal_error; + } + free(du); + } + blk->fec_du_head = NULL; + blk->fec_du_nb_in_list = 0; + TRACELVL(5, (mcl_stdout, "<- mcl_fec::decode(LDPC-*): ok\n")) + return 1; + } + /* + * not finished... keep state for next call to this function + */ + TRACELVL(5, (mcl_stdout, "<- mcl_fec::decode(LDPC-*): not finished\n")) + return 0; + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_fec::decode(LDPC-*): ERROR, no memory")) +fatal_error: + mcl_exit(-1); + return -1; /* unreachable; avoid a compiler warning */ +} + + +/** + * This callback function will be called each time a packet + * is decoded by the DecodeFecStep() function. + * => See header file for more informations. + */ +void * +mcl_fec::decoded_pkt_callback (void *context, + INT32 size, + INT32 pkt_seq) +{ + mcl_cb *mclcb; // associated mclcb + block_t *blk; // associated block + mcl_rx_pkt *pkt; // packet buffer + du_t *du; // DU associated to pkt to create + UINT32 du_len; // full-sized DU length + UINT32 last_du_len; // last DU (true) length + int err; + + ASSERT(context); + mclcb = ((ldpc_callback_context_t*)context)->mclcb; + ASSERT(mclcb); + blk = ((ldpc_callback_context_t*)context)->block; + ASSERT(blk); + TRACELVL(5, (mcl_stdout, "-> mcl_fec::decoded_pkt_callback:\n")) + + pkt = new mcl_rx_pkt (size); + ASSERT(pkt); + pkt->pkt_len = size; + + //du = new mcl_du; + du = CreateDU(mclcb); + /* next = prev = NULL */ + du->block = blk; + du->seq = pkt_seq; + /* + * compute the size of a full-sized DU and of the last DU + * which may be shorter + */ + //du_len = mclcb->get_payload_size(); + //du_len = mclcb->payload_size; + du_len=blk->adu->symbol_len; + if (pkt_seq == (int)blk->k - 1) { + /* last packet of the block, may be shorter */ + last_du_len = (blk->k > 1) ? blk->len % du_len : blk->len; + if (last_du_len == 0) + last_du_len = du_len; /* multiple */ + du->len = last_du_len; + } else { + /* full sized packet */ + du->len = du_len; + } + ASSERT(pkt_seq < (int)blk->k); /* make sure it's a source packet */ + du->is_fec = false; + //du->set_next(NULL); + //du->set_prev(NULL); + du->data = pkt->get_buf(); + du->pkt = pkt; + /* + * and insert it in the data DU list + */ + err = InsertDU(mclcb, du, &(blk->du_head)); + ASSERT(err == 1); + blk->du_nb_in_list++; + blk->adu->recvd_src_data += du->len; + + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::decoded_pkt_callback: created aseq=%d/bseq=%d/dseq=%d %s\n", + blk->adu->seq, blk->seq, du->seq, + (du->is_fec ? "FEC" : "DATA"))) + return (du); +} + + +/** + * This callback function will be called each time the + * DecodeFecStep() function needs to allocate a buffer. + */ +void * +mcl_fec::alloc_tmp_buffer_callback (void *context, + int size) +{ + mcl_cb *mclcb; // associated mclcb + mcl_rx_pkt *pkt; // buffer + du_t *du; // DU associated to buffer to create + + ASSERT(context); + mclcb = ((ldpc_callback_context_t*)context)->mclcb; + ASSERT(mclcb); + TRACELVL(5, (mcl_stdout, "-> mcl_fec::alloc_tmp_buffer_callback:\n")) + + pkt = new mcl_rx_pkt (size); + ASSERT(pkt); + pkt->pkt_len = size; + // we need a DU descriptor, even for temporary buffers, + // since this is the data type used for LDPC codec/MCLv3 + // interface. + //du = new mcl_du; + du = CreateDU(mclcb); + du->len = size; + du->data = pkt->get_buf(); + du->pkt = pkt; + + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::alloc_tmp_buffer_callback: du->data=x%x, len=%d\n", + (INT32)du->data, du->len)) + return ((void*)du); +} + + +void * +mcl_fec::get_data_callback (void *context, + void *pkt_du) +{ +#ifdef VIRTUAL_RX_MEM + mcl_cb *mclcb; // associated mclcb + + ASSERT(context); + mclcb = ((ldpc_callback_context_t*)context)->mclcb; + ASSERT(mclcb); + /* + * retrieve data buffer that may be stored only on disk!!! + */ + if (mclcb->rx_storage.get_data(mclcb, (du_t*)pkt_du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::get_data_callback: ERROR: get_data() failed\n")) + mcl_exit(-1); + } + TRACELVL(5, (mcl_stdout, + " mcl_fec::get_data_callback: pkt_du->data=x%x, len=%d\n", + (INT32)((du_t*)pkt_du)->data, ((du_t*)pkt_du)->len)) +#endif + return ((void*)((du_t*)pkt_du)->data); +} + + +void * +mcl_fec::get_data_ptr_only_callback (void *context, + void *pkt_du) +{ +#ifdef VIRTUAL_RX_MEM + mcl_cb *mclcb; // associated mclcb + + ASSERT(context); + mclcb = ((ldpc_callback_context_t*)context)->mclcb; + ASSERT(mclcb); + TRACELVL(5, (mcl_stdout, + " mcl_fec::get_data_ptr_only_callback: pkt_du->data=x%x, len=%d\n", + (INT32)((du_t*)pkt_du)->data, ((du_t*)pkt_du)->len)) + ASSERT(((du_t*)pkt_du)->data); +#endif + return ((void*)((du_t*)pkt_du)->data); +} + + +/** + * This callback function will be called each time data must + * be stored permanently. + * => See header file for more informations. + */ +ldpc_error_status +mcl_fec::store_data_callback (void *context, + void *pkt_du) +{ + mcl_cb *mclcb; // associated mclcb + + ASSERT(context); + mclcb = ((ldpc_callback_context_t*)context)->mclcb; + ASSERT(mclcb); + TRACELVL(5, (mcl_stdout, + "-> mcl_fec::store_data_callback: pkt_du->len=%d\n", + ((du_t*)pkt_du)->len)) + /* + * store data buffer either in vrfile (when desired and needed) + * or in physical memory, whichever is the most appropriate. + */ + if (mclcb->rx_storage.store_data(mclcb, (du_t*)pkt_du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::store_data_callback: ERROR: store_data() failed\n")) + mcl_exit(-1); + } + TRACELVL(5, (mcl_stdout, "<- mcl_fec::store_data_callback:\n")) + return LDPC_OK; +} + + +ldpc_error_status +mcl_fec::free_pkt_callback (void *context, + void *pkt_du) +{ + mcl_cb *mclcb; // associated mclcb + + ASSERT(context); + mclcb = ((ldpc_callback_context_t*)context)->mclcb; + ASSERT(mclcb); + TRACELVL(5, (mcl_stdout, "-> mcl_fec::free_pkt_callback:\n")) + if (mclcb->rx_storage.free_data(mclcb, (du_t*)pkt_du) == MCL_ERROR) { + return LDPC_ERROR; + } + TRACELVL(5, (mcl_stdout, "<- mcl_fec::free_pkt_callback:\n")) + return LDPC_OK; +} + +#endif /* LDPC_FEC */ + diff --git a/src/alc/mcl_fec.h b/src/alc/mcl_fec.h new file mode 100644 index 0000000..87f221d --- /dev/null +++ b/src/alc/mcl_fec.h @@ -0,0 +1,500 @@ +/* $Id: mcl_fec.h,v 1.16 2005/05/17 12:36:57 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_FEC_H /* { */ +#define MCL_FEC_H + + +/** + * The following defines are specifying the identifiers used by + * the ALC/LCT protocol. See RFC 3452 for further details. + */ + +/** + * FEC Encoding ID (RFC 3452). + * It determines the FTI format and is carried in the LCT codepoint + * header field. + */ +#define FEC_ENCODING_ID_NO_FEC 0 +#define FEC_ENCODING_ID_SMALL_LARGE_EXP_FEC 128 +#define FEC_ENCODING_ID_SMALL_SYSTEMATIC_FEC 129 +// Parity Check Matrix based FEC codes. +// see the draft-peltotalo-rmt-bb-fec-xor-pcm-rs-XX.txt I-D... +#define FEC_ENCODING_ID_PCM_FEC 132 + + +#ifdef LDPC_FEC +/** + * context used as an opaque parameter to decoded_pkt_callback. + */ +typedef struct ldpc_callback_context { + class mcl_cb *mclcb; + block_t *block; +} ldpc_callback_context_t; +#endif + + +/** + * Main FEC class. + * Shared by the various FEC codecs. + */ +class mcl_fec { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + * Initializes all the supported FEC code parameters. + * Initializes the default FEC code. + */ + mcl_fec (); + + ~mcl_fec (); + + /** + * Initializes the FEC class for all supported FEC codes: + * MCL_FEC_SCHEME_NULL, ...RSE, ...LDGM, ...LDPC. + * (see mcl_lib_api_alc.h). + * Initializes the default constructor. + */ + void initialize (void); + + /** + * Return the maximum block size (in number of DUs). + * This parameter is set at mcl_fec service initialization + * depending on the FEC code used, and is READ-ONLY. + * We have: max_k <= max_n (no FEC DU if equal). + * @return maximum k. + */ + INT32 get_max_k () const; + + /** + * Return the maximum n value for a block (in number of DUs). + * This parameter is set at mcl_fec service initialization + * depending on the FEC code used, and is READ-ONLY. + * @return maximum n. + */ + INT32 get_max_n () const; + + /** + * Set the effective block size to use (in number of DUs). + * 0 < k <= max_k made possible by the code. + * If k == n, then no FEC DU will be produced. + * @param k new k value. + */ + void set_k (const INT32 k); + + /** + * Return the effective block size used currently (in number of DUs). + * @return effective k value to use. + */ + INT32 get_k (void) const; + + /** + * Set the effective n value to use (in number of DUs). + * 0 < n <= max_n made possible by the code. + * If k == n, then no FEC DU will be produced. + * @param n new n value to use. + */ + void set_n (const INT32 n); + + /** + * Return the effective n parameter used currently (in number of DUs). + * @return effective n value. + */ + INT32 get_n (void) const; + + /** + * Set the FEC code to be used. + * This function is sender specific (a receiver gets the FEC + * codec information info from the various incoming packet fields). + * This function only changes the FEC code to use from now on, + * without modifying anything else. It assumes that the FEC + * codec specific parameters have already been initialized. + * @param mclcb + * @param new_code FEC code to use from now on, in: + * {MCL_FEC_SCHEME_NULL; MCL_FEC_SCHEME_RSE; + * MCL_FEC_SCHEME_LDGM; MCL_FEC_SCHEME_LDPC} + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_fec_code (class mcl_cb *const mclcb, + const INT32 new_code); + + /** + * Return the FEC code corresponding to the current FEC codec used. + * @return FEC scheme value in: + * {MCL_FEC_SCHEME_NULL; MCL_FEC_SCHEME_RSE; + * MCL_FEC_SCHEME_LDGM; MCL_FEC_SCHEME_LDPC} + */ + mcl_fec_scheme get_fec_code () const; + + /** + * Return the FEC code string corresponding to the current FEC codec + * used. + * WARNING: non re-entrant, the string is statically allocated... + * @return string with the name of the FEC code. + */ + char* get_fec_code_string () const; + + /** + * Set the current FEC ratio, defined as cur_n/cur_k, and update + * either cur_n or cur_k, depending on the FEC codec. + * Note that this ratio only applies to the current FEC codec, not + * to others, so set the FEC codec first before setting the FEC ratio! + * With RSE, from the cur_n value, it defines the new cur_k value, + * and checks it is reasonable (e.g. >= 1). + * With LDPC, from the cur_k value, it defines the new cur_n value, + * and checks it is compatible with the max_n value. + * This is required by the fact that the n parameter is not carried + * by the EXT_FTI associated to FEC encoding ID 128 and 130 (i.e. + * used by NULL and RSE), unlike our private FEC encoding ID 140! + * It means that the appropriate FEC ratio must be set by both the + * sender AND receiver with FEC encoding IDs 128 and 130, but only + * at the sender with our FEC encoding ID 140. + * The above settings for cur_k and cur_n are only valid for blocks + * of maximum size. Otherwise, with smalle blocks, the n value + * associated to k < cur_k is calculated from the cur_n/cur_k ratio. + * + * @param mclcb + * @param new_fec_ratio desired FEC ratio + * @return Completion status (MCL_OK or MCL_ERROR). + * If the new n or k value is invalid, then + * an error is returned. + */ + mcl_error_status set_fec_ratio (class mcl_cb *const mclcb, + double new_fec_ratio); + + /** + * Return the current FEC ratio, defined as cur_n/cur_k. + */ + double get_fec_ratio () const; + + /** + * Converts from FEC Encoding ID/FEC Instance ID to FEC scheme. + * @param encid FEC Encoding ID + * @param instid FEC Instance ID + * @param scheme pointer to FEC scheme variable to store the + * result. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status enc_inst_to_scheme ( + class mcl_cb *const mclcb, + UINT8 encid, + UINT8 instid, + mcl_fec_scheme *scheme); + + /** + * Converts from FEC scheme to FEC Encoding ID/FEC Instance ID. + * @param scheme FEC scheme + * @param encid pointer to FEC Encoding ID variable to store + * the result. + * @param instid pointer to FEC Instance ID variable to store + * the result. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status scheme_to_enc_inst ( + class mcl_cb *const mclcb, + mcl_fec_scheme scheme, + UINT8 *encid, + UINT8 *instid); + +#if 0 + /** + * Return the number of available FEC packets (ie that have been + * created) that have not yet been sent. + * @param mclcb + * @return + */ + INT32 get_nb_fresh_fec_pkts (mcl_cb *const mclcb, + mcl_block *blk); +#endif + + /** + * Return the number of FEC packets that can still be created for this + * block. + * @param mclcb + * @param blk block + * @return Number of FEC packets that can still be + * created for this block. + */ + INT32 get_rem_nb_fec_pkts_to_create (class mcl_cb *const mclcb, + block_t *blk); + +#ifdef FEC + /** + * Encode the block and create the appropriate number of new FEC + * packets. + * The FEC packets are inserted in the block FEC list. (XXX: not yet) + * The number of FEC packets created is automatically determined + * by the block size and scheduling session. + * @param mclcb + * @param blk block for which FEC packets must be created + * @return < 0 if error, the number of FEC symbols + * created if ok + */ + INT32 encode (class mcl_cb *const mclcb, + block_t *blk); +#endif + +#ifdef RSE_FEC + /** + * Decode the block immediately. + * This function is for Reed-Solomon and similar FEC codes who, + * thanks to their MDS feature, decode blocks as a whole, as soon + * as enough (i.e. blk->k) packets have been received. + * @param mclcb + * @param blk block for which decoding must be done + * @return < 0 if error, the number of FEC symbols + * created if ok + */ + INT32 decode (class mcl_cb *const mclcb, + block_t *blk); + +#endif /* RSE_FEC */ + +#ifdef LDPC_FEC + /** + * Progress in the block decoding with the given packet. + * This function is for LDPC and similar FEC codes who use an + * iterative decoding approach. + * @param mclcb + * @param rx_du DU for the packet just received + * @return < 0 if error, the number of FEC symbols + * created if ok + */ + INT32 decode (class mcl_cb *const mclcb, + du_t *rx_du); + + /** + * Test if decoding is completed for this block. + * @param blk block concerned + * @return true if completed, false if there are + * missing source packets. + */ + bool is_decoding_complete (block_t *blk); +#endif /* LDPC_FEC */ + + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + + /** + * Set the current FEC ratio, defined as cur_n/cur_k, from n, and + * update cur_k. + * @param mclcb + * @param new_fec_ratio desired FEC ratio + * @return Completion status (MCL_OK or MCL_ERROR). + * If the new k value is invalid, then + * an error is returned. + */ + mcl_error_status set_fec_ratio_from_n + (class mcl_cb *const mclcb, + double new_fec_ratio); + + /** + * Set the current FEC ratio, defined as cur_n/cur_k, from k, and + * update cur_n. + * @param mclcb + * @param new_fec_ratio desired FEC ratio + * @return Completion status (MCL_OK or MCL_ERROR). + * If the new n value is invalid, then + * an error is returned. + */ + mcl_error_status set_fec_ratio_from_k + (class mcl_cb *const mclcb, + double new_fec_ratio); + + /** + * Determine the number of FEC packets required for this block. + * Depends on the block size (k) and the kind of scheduling used + * for this session. + * Only used by a sender. + * @param mclcb + * @param k k parameter for this block + * @return n parameter for this block + */ + INT32 compute_n_for_this_block (class mcl_cb *const mclcb, + INT32 k); + +#ifdef LDPC_FEC + /** + * This callback function will be called each time a packet + * is decoded by the DecodeFecStep() function. + * Create the associated DU, and insert the packet in the rx list. + * Allocate the buffer, using the VRM service if applicable. + * This function is STATIC to enable pointer-to-member-function. + * @param pkt_buf pointer to the packet buffer + * @param pkt_seq sequence number of packet in block + * ({0..n-1} range). Can be used to + * differentiate source and FEC packets. + * @param context pointer to an ldpc_callback_context_t + * structure. + */ + static void *decoded_pkt_callback (void *context, + INT32 size, + INT32 pkt_seq); + + /** + * This callback function will be called each time the + * DecodeFecStep() function needs to allocate a buffer. + * Allocate the buffer, using the VRM service if applicable, + * and return the buffer. This function replaces malloc(). + * This function is STATIC to enable pointer-to-member-function. + * @param context pointer to an ldpc_callback_context_t + * structure. + * @param size buffer size to allocate. + * @return pointer to the buffer allocated, or NULL + * in case of error. + */ + static void *alloc_tmp_buffer_callback (void *context, + int size); + + /** + * This callback function will be called each time an + * LDPC codec function needs to access a buffer associated + * to a packet. + */ + static void *get_data_callback (void *context, + void *pkt_du); + + /** + * Same as get_data_callback, except that no check is made + * concerning the availability of data. + */ + static void *get_data_ptr_only_callback (void *context, + void *pkt_du); + + /** + * This callback function will be called each time an + * LDPC codec function needs to make sure a buffer associated + * to a packet is stored permanently. + */ + static ldpc_error_status + store_data_callback (void *context, + void *pkt_du); + + /** + * This callback function will be called each time an + * LDPC codec function needs to free a packet/buffer previously + * allocated with decoded_pkt_callback or alloc_tmp_buffer_callback. + */ + static ldpc_error_status + free_pkt_callback (void *context, + void *pkt_du); + + +#endif /* LDPC_FEC */ + + + /****** Private Attributes ********************************************/ + + mcl_fec_scheme fec_codec; + /* Codec to use for this session. + * Can be one of MCL_FEC_SCHEME_NULL, ...RSE, + * ...LDGM, ...LDPC. + */ + + /* max_X are _statically_ defined, at initialization */ + INT32 max_k[MCL_FEC_SCHEME_NB]; /** Max k value. FEC dependant */ + INT32 max_n[MCL_FEC_SCHEME_NB]; /** Max n value. FEC dependant */ + /* cur_X are initialized with default values, but they can be + * overriden latter on by the user */ + INT32 cur_k[MCL_FEC_SCHEME_NB]; /** k value currently in use. */ + INT32 cur_n[MCL_FEC_SCHEME_NB]; /** n value currently in use. */ +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline INT32 +mcl_fec::get_max_k () const +{ + return this->max_k[this->fec_codec]; +} + +inline INT32 +mcl_fec::get_max_n () const +{ + return this->max_n[this->fec_codec]; +} + +inline INT32 +mcl_fec::get_k (void) const +{ + return this->cur_k[this->fec_codec]; +} + +inline void +mcl_fec::set_k (const INT32 k) +{ + ASSERT(k <= max_k[this->fec_codec]); + ASSERT(k > 0); + ASSERT(k <= cur_n[this->fec_codec]); + this->cur_k[this->fec_codec] = k; +} + +inline INT32 +mcl_fec::get_n () const +{ + return this->cur_n[this->fec_codec]; +} + +inline void +mcl_fec::set_n (const INT32 n) +{ + ASSERT(n <= max_n[this->fec_codec]); + ASSERT(n > 0); + ASSERT(cur_k[this->fec_codec] <= n); + this->cur_n[this->fec_codec] = n; +} + +inline mcl_fec_scheme +mcl_fec::get_fec_code () const +{ + /* + * WARNING: assumes that lct_codepoint values are the same + * as the MCL_FEC_CODE_XXX values! + */ + return (mcl_fec_scheme) this->fec_codec; +} + +inline double +mcl_fec::get_fec_ratio () const +{ + return ((double)this->get_n() / (double)this->get_k()); +} + +#ifdef LDPC_FEC +inline bool +mcl_fec::is_decoding_complete (block_t *blk) +{ + ASSERT(blk->ldpc_ses); + ASSERT(blk->pkt_canvas); + return (blk->ldpc_ses->IsDecodingComplete(blk->pkt_canvas)); +} +#endif + +#endif /* } MCL_FEC_H */ diff --git a/src/alc/mcl_flid_sl.cpp b/src/alc/mcl_flid_sl.cpp new file mode 100644 index 0000000..58ae780 --- /dev/null +++ b/src/alc/mcl_flid_sl.cpp @@ -0,0 +1,585 @@ +/* $Id: mcl_flid_sl.cpp,v 1.17 2005/01/11 13:12:27 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * LCC congestion control module FLID SL (Static Layer). + */ + +#include "mcl_includes.h" + +#ifdef FLIDS /* { */ + + +/* + * Local private function prototypes + */ +static INT32 CheckSequence (mcl_cb *mclcb, UINT8 layer, UINT16 seqid, + UINT8 tsi); +static INT32 AddLate (mcl_cb *mclcb, INT32 layer, INT32 nseq); +static INT32 RemoveLate (mcl_cb *mclcb, INT32 layer, INT32 nseq); +static void ComputeTSI (mcl_cb *mclcb); + + +/****** PUBLIC FUNCTIONS ******************************************************/ + + +/** + * Initializes the RLC congestion control mechanism for a given session. + * => See header file for more informations. + */ +void +FLIDs_InitSession (mcl_cb *mclcb) +{ + INT32 i; + flids_cb_t *cb; + + TRACELVL( 5, (mcl_stdout, + "-> FLIDs: FLIDs_InitSession: mclcb=x%x\n", (int) mclcb)) + /* WARNING: no use of modes? */ + cb = &(mclcb->flids_cb); + memset((void *)cb, 0, sizeof(flids_cb_t)); + + cb->SessionState = 1; /* Initial State */ + cb->tsd = FLIDS_TSD; + cb->tsi = 0; + cb->long_tsi = 0; + cb->rx_CongestionDetected = 0; + cb->rx_DeafPeriod = 0; + cb->flids_deaf_period = FLIDS_DEAF_PERIOD; + cb->flids_tx_timer_count = 0; + + for( i=0; irx_LayerState[i] = 1; + cb->tx_LayerSeq[i] = 0; + cb->rx_IncreaseTrigger[i] = 0; + cb->rx_WaitFor[i] = 0; + cb->tx_LayerTrig[i] = 0; + } + + TRACELVL(5, (mcl_stdout, "<- FLIDs: FLIDs_InitSession\n")) +} + + +/** + * Must be called when ending a session. + * => See header file for more informations. + */ +void +FLIDs_EndSession (mcl_cb *mclcb ) +{ + TRACELVL(5, (mcl_stdout, "-> FLIDs: FLIDs_EndSession\n")) + // Nothing... + TRACELVL(5, (mcl_stdout, "<- FLIDs: FLIDs_EndSession\n")) +} + + +/** + * Timer function, called periodically by the sender. + * => See header file for more informations. + */ +void +FLIDs_TxTimer (mcl_cb *mclcb) +{ + FLIDs_NewTimeSlot(mclcb); +} + + +/** + * Increase the Time Slot Index (TSI) periodically (the period is TSD). + * => See header file for more informations. + */ +void +FLIDs_NewTimeSlot (mcl_cb *mclcb) +{ + flids_cb_t *cb; + + TRACELVL(5, (mcl_stdout, "-> FLIDs: FLIDs_NewTimeSlot\n")) + ASSERT(mclcb!=NULL) + cb = &(mclcb->flids_cb); + + cb->tsi = (cb->tsi+1)%128; /* WARNING: why not using 8bits for TSI? */ + cb->long_tsi++; + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tnew_TS %ld\n", + time.tv_sec, time.tv_usec, cb->long_tsi)) + } + ComputeTSI(mclcb); + TRACELVL(5, (mcl_stdout, "<- FLIDs: FLIDs_NewTimeSlot\n")) +} + + +/** + * Build the FLID-SL header for each packet to send. + * => See header file for more informations. + */ +INT32 +FLIDs_tx_FillHeader (mcl_cb *mclcb, + flids_hdr_t *hdr_buff, + UINT8 grp_idx) +{ + UINT16 hdr_seqno; + flids_cb_t *cb; + + TRACELVL(5, (mcl_stdout, + "-> FLIDs: FLIDs_tx_FillHeader: mclcb=x%x, grp_idx=%d\n", + (int) mclcb, grp_idx)) + ASSERT(mclcb!=NULL) + cb = &(mclcb->flids_cb); + + ASSERT(grp_idx < MAX_NB_TX_LAYERS && grp_idx < mclcb->nb_layers) + ASSERT(hdr_buff!=NULL) + + hdr_seqno = cb->tx_LayerSeq[grp_idx]; + (cb->tx_LayerSeq[grp_idx])++; + + hdr_buff->seqno = htons(hdr_seqno); /* Sequence number */ + hdr_buff->gn = grp_idx; /* Index of the group */ + hdr_buff->tsi = cb->tsi; /* Time Slot Index */ + + hdr_buff->trigger = cb->tx_LayerTrig[grp_idx]; + + if (mclcb->get_verbosity() == 2 && (hdr_seqno%10==0)) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tist_bit %d %d\n", + time.tv_sec, time.tv_usec, hdr_buff->trigger, grp_idx)) + } + + TRACELVL(5, (mcl_stdout, "<- FLIDs: FLIDs_tx_FillHeader: ok\n")) + return MCL_OK; +} + + +/** + * Analyze the packet FLID-SL header. + * => See header file for more informations. + */ +INT32 +FLIDs_rx_AnalyzePacket (mcl_cb *mclcb, + flids_hdr_t *hdr_buff) +{ + UINT8 groupn; + UINT16 seqno; + UINT8 pkt_tsi; + UINT8 new_tsi; + UINT8 trigger; + flids_cb_t *cb; + + ASSERT(hdr_buff!=NULL) + TRACELVL(5, (mcl_stdout, "-> FLIDs: FLIDs_rx_AnalyzePacket\n")) + ASSERT(mclcb!=NULL) + cb = &(mclcb->flids_cb); + + pkt_tsi = hdr_buff->tsi; + new_tsi = pkt_tsi; + trigger = hdr_buff->trigger; + groupn = hdr_buff->gn; + seqno = ntohs(hdr_buff->seqno); + + // printf("FLIDs_PKT layer=%d seq=%d\n", groupn, seqno); + if(groupn >= mclcb->nb_layers) { + /* Bad group number, so ignore... */ + TRACELVL(5, (mcl_stdout, "<- FLIDs: FLIDs_rx_AnalyzePacket (BAD_LAYER)\n")) + return ERR_BAD_LAYER; + } + + if (mclcb->get_verbosity() == 2 && (seqno%10==0)) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tist_bit %d %d\n", + time.tv_sec, time.tv_usec, trigger, groupn)) + } + + if( cb->SessionState == 1 ) { + /* Session First Packet */ + cb->tsi = pkt_tsi; + cb->SessionState = 2; + cb->rx_WaitFor[groupn] = seqno + 1; + cb->rx_LayerState[groupn] = 3; + cb->rx_IncreaseTrigger[groupn] = trigger; + goto end; + } + + if( cb->rx_LayerState[groupn] == 1) { + /* First packet on this group... (or first packet for a + * readded group) */ + cb->rx_WaitFor[groupn] = seqno + 1; + cb->rx_LayerState[groupn]=3; + cb->rx_IncreaseTrigger[groupn] = trigger; + goto end; + } else { + /* check if some pkts have been lost or not */ + new_tsi = CheckSequence(mclcb, groupn, seqno, pkt_tsi); + } + + /* First Packet (no matter the group) for this TimeSlot... DECISION + * HERE */ + if( new_tsi != cb->tsi ) { + INT32 i = 0; + + if( new_tsi != (cb->tsi+1)%128 ) { + TRACELVL(4, (mcl_stdout, + "FLIDs WARNING! Unexpected TSI Value (Old=%d, New=%d), packets have probably been lost\n",cb->tsi, new_tsi)) + } + + cb->tsi = new_tsi; + TRACELVL(3, (mcl_stdout, + "FLIDs: Entering NEW Time Slot (tsi=%d, trigger was %d)\n", + cb->tsi, cb->rx_IncreaseTrigger[mclcb->nb_layers-1])) + + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tnew_TS %d\n", + time.tv_sec, time.tv_usec, cb->tsi)) + } + + if (cb->rx_DeafPeriod > 0 ) { + cb->rx_DeafPeriod--; + if (cb->rx_DeafPeriod == 0 && mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((stdout, + "\n%ld.%06ld\tend_deaf\n", + time.tv_sec, time.tv_usec)) + } + } + + for(i=0; irx_LayerState[i] = 2; + } + + if (cb->rx_CongestionDetected) { + if(!cb->rx_DeafPeriod) { + /* too many losses... drop a layer! */ + if (mcl_drop_layer(mclcb, MCL_HIGHEST_LAYER, MCL_DO_IT ) < 0) { + /* error, cannot drop layer */ + TRACELVL(3, (mcl_stdout, + "<- FLIDs: cant drop layer, ignore\n")) + } else { + TRACELVL(2, (mcl_stdout, + " FLIDs: congestion detected, highest layer dropped, now receiving from %d layers\n", mclcb->nb_layers)) + /* Entering Deaf Period... */ + cb->rx_DeafPeriod = cb->flids_deaf_period; + /* initial state for futur potential + * use of this layer*/ + cb->rx_LayerState[mclcb->nb_layers]=1; + } + } + cb->rx_CongestionDetected = 0; + goto end; + + } else if(cb->rx_IncreaseTrigger[mclcb->nb_layers-1]) { + if (mcl_add_layer(mclcb, MCL_HIGHEST_LAYER) == 0) + { + cb->rx_LayerState[mclcb->nb_layers-1]=1; + TRACELVL(2, (mcl_stdout, + " FLIDs: adding a new layer, now receiving from %d layers\n", mclcb->nb_layers)) + } + } + cb->rx_CongestionDetected = 0; + + } + + ASSERT(cb->tsi == new_tsi) + + // HACK: if no packets received during a complete timeslot then + // FLIDs should [MAYBE] crash HERE ;) + + if(cb->rx_LayerState[groupn]==2) { + // First Packet ON THIS GROUP FOR THIS TIMESLOT + cb->rx_IncreaseTrigger[groupn] = trigger; + cb->rx_LayerState[groupn]=3; + TRACELVL(3, (mcl_stdout, + "First Packet for Layer %d for Timeslot %d\n", groupn, new_tsi)) + } else { + ASSERT(cb->rx_LayerState[groupn]==3) + + if(cb->rx_IncreaseTrigger[groupn] != trigger) { + TRACELVL(5, (mcl_stdout, + "<- FLIDs: FLIDs_rx_AnalyzePacket (BAD_TRIGGER)\n")) + return ERR_BAD_TRIGGER; + } + } + +end: + TRACELVL(5, (mcl_stdout, "<- FLIDs: FLIDs_rx_AnalyzePacket (ok)\n")) + return groupn; +} + + +/** + * Used to set various FLID-SL options and parameters. + * => See header file for more informations. + */ +mcl_error_status +FLIDs_ctl (mcl_cb *mclcb, INT32 optname, void *optvalue, INT32 optlen) +{ + flids_cb_t *cb = &(mclcb->flids_cb); + + TRACELVL(5, (mcl_stdout, + "-> FLIDs: FLIDs_ctl: optname=%d, optvalue=x%x, optlen=%d\n", + optname, (int)optvalue, optlen)) + + switch (optname) { + case FLIDS_OPT_DEAF_PERIOD: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "FLIDs_ctl ERROR FLIDS_OPT_DEAF_PERIOD: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < 0 ) { + PRINT_ERR((mcl_stderr, + "FLIDs_ctl ERROR: FLIDS_OPT_DEAF_PERIOD must be positive (got %d)\n",(*(int*)optvalue))) + goto error; + } + cb->flids_deaf_period = *(int*)optvalue; + break; + + case FLIDS_OPT_TSD: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "FLIDs_ctl ERROR FLIDS_OPT_TSD: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < 0 ) { + PRINT_ERR((mcl_stderr, + "FLIDs_ctl ERROR: FLIDS_OPT_TSD must be positive (got %d)\n",(*(int*)optvalue))) + goto error; + } + cb->tsd = *(int*)optvalue; + break; + + default: + PRINT_ERR((mcl_stderr, + "<- FLIDs: FLIDs_ctl: ERROR, Unknown option\n")) + goto error; + } + + TRACELVL(5, (mcl_stdout, "<- FLIDs: FLIDs_ctl: ok\n")) + return MCL_OK; + +error: + TRACELVL(5, (mcl_stdout, "<- FLIDs: FLIDs_ctl: ERROR\n")) + return MCL_ERROR; +} + + +/****** PRIVATE FUNCTIONS *****************************************************/ + + +/** + * Return NEW CURRENT TSI... + */ +static int +CheckSequence (mcl_cb *mclcb, + UINT8 layer, + UINT16 seqid, + UINT8 tsi) +{ + flids_cb_t *cb; + UINT16 Delta1; + UINT16 Delta2 = 0; + UINT16 i; /* must be u_int16! */ + UINT8 NewTSI; + + ASSERT(mclcb) + cb = &(mclcb->flids_cb); + + TRACELVL(5, (mcl_stdout, + "-> FLIDs: CheckSequence: seqid=%d (expected seq %d)\n", + seqid, cb->rx_WaitFor[layer])) + + if ( cb->rx_WaitFor[layer] == seqid) { + /* This is the packet we're waiting for, let's go on! */ + //cb->rx_WaitFor[layer] = (cb->rx_WaitFor[layer] + 1) % 65536; + cb->rx_WaitFor[layer]++; // u_int16, so wrapping is automatic + TRACELVL(5, (mcl_stdout, "<- FLIDs: CheckSequence: good seq\n")) + NewTSI = tsi; + return NewTSI; + } + + /* This is not the one we're waiting for... */ + if (cb->rx_WaitFor[layer] < seqid) { + Delta1 = seqid - cb->rx_WaitFor[layer]; + Delta2 = 65535 - Delta1; + if ( Delta1 < Delta2 ) { + /* Some packet(s) are missing */ + /* eg. wait seq 1512 and get 1513, so 1512 is missing */ + for (i = cb->rx_WaitFor[layer]; i < seqid; i++) + { + AddLate(mclcb, layer, i); + } + //cb->rx_WaitFor[layer] = (seqid + 1) % 65536; + cb->rx_WaitFor[layer] = seqid + 1; + NewTSI = tsi; + } else { + /* Late arrival packet (uint16 overflow) */ + /* eg. we're waiting seq 4 and we get seq 65532 */ + RemoveLate(mclcb, layer, seqid); + NewTSI = cb->tsi; + } + } else { + /* rx_WaitFor > seqid */ + Delta1 = cb->rx_WaitFor[layer] - seqid; + Delta2 = 65535 - Delta1; + if ( Delta1 < Delta2 ) { + /* Late arrival packet */ + /* eg. we're waiting seq 501 and we get seq 498 */ + RemoveLate(mclcb, layer, seqid); + NewTSI = cb->tsi; + } else { + /* Some packet(s) are missing (uint16 overflow) */ + /* eg. we're waiting seq 65531 and we get seq 3 */ + for (i = cb->rx_WaitFor[layer]; i != (seqid-1); i++) { + AddLate(mclcb, layer, i); + } + //cb->rx_WaitFor[layer] = (seqid + 1) % 65536; + cb->rx_WaitFor[layer] = seqid + 1; + NewTSI = tsi; + } + } + + /* + * All kinds of problems, including late packet arrivals and + * duplicated packets, are signs of problems... So raise the + * congestion status and take appropriate measures. + */ + if (!cb->rx_CongestionDetected) { + cb->rx_CongestionDetected = 1; + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, + "\n%ld.%06ld\tloss_detected %d %d %d\n", + time.tv_sec, time.tv_usec, + layer, seqid, cb->rx_CongestionDetected)) + } + } + + TRACELVL(5, (mcl_stdout, "<- FLIDs: CheckSequence: seq broken\n")) + return NewTSI; +} + + +/** + * A packet is late, remember there is one. + */ +static int +AddLate (mcl_cb *mclcb, + INT32 layer, + INT32 nseq) +{ + ASSERT(mclcb != NULL && layer <= mclcb->nb_layers) + /* update stats: assume a late pkt is lost (corrected later if req.) */ + mclcb->stats.rx_lost_pkts++; + mclcb->stats.rx_lost_per_lvl[layer]++; + TRACELVL(3, (mcl_stdout, + " FLIDs: pkt %d of layer %d late\n", nseq, layer)) + return MCL_OK; +} + + +/** + * We finally received the delayed packet. + */ +static int +RemoveLate (mcl_cb *mclcb, + INT32 layer, + INT32 nseq) +{ + ASSERT(mclcb != NULL && layer <= mclcb->nb_layers) + /* correct stats... */ + mclcb->stats.rx_lost_pkts--; + mclcb->stats.rx_lost_per_lvl[layer]--; + TRACELVL(3, (mcl_stdout, + " FLIDs: pkt %d of layer %d finally arrived\n", nseq, layer)) + return MCL_OK; +} + + +static void +ComputeTSI (mcl_cb *mclcb) +{ + flids_cb_t *cb; + double P = 0.0; + long B = 0; + double BB=0.0; + txlay_t *tl; + //INT32 LevelTotBw = 0; + double LevelTotBw = 0; // cumulative tx rate up to and including + // this layer in Bytes per second + INT32 i=0; + + ASSERT(mclcb!=NULL) + cb = &(mclcb->flids_cb); + + for( i=0; itx_LayerTrig[i] = 0; + } + + B = cb->long_tsi; + for(i=1; B!=0; i++) { + BB += ((double)(B%2)) / pow(2.0, i); + B >>= 1; + } + + for( i=0; i < mclcb->nb_layers; i++) { + tl = &(mclcb->txlay_tab[i]); + LevelTotBw = tl->cumul_du_per_tick * mclcb->get_payload_size() * + mcl_periodic_timer::get_frequency(); // in Bytes/sec + + if ( i+1 == mclcb->nb_layers) { + /* Last Layer */ + P = 0.0; + } else { + P = min(1.0, + (20.0 * (double)mclcb->get_payload_size () * + (cb->tsd/1000000)) / (double)LevelTotBw ); + } + + if(BB <= P) { + /* Increase Signal Trigger */ + cb->tx_LayerTrig[i] = 1; + } else { + cb->tx_LayerTrig[i] = 0; + } + } + +#ifdef DEBUG + for(i = mclcb->nb_layers-1; i>0; i--) { + if (cb->tx_LayerTrig[i] == 1) { + ASSERT(cb->tx_LayerTrig[i-1]==1) + } + } +#endif /* DEBUG */ +} + + + + +#endif /* } FLIDS */ + diff --git a/src/alc/mcl_flid_sl.h b/src/alc/mcl_flid_sl.h new file mode 100644 index 0000000..092bbb7 --- /dev/null +++ b/src/alc/mcl_flid_sl.h @@ -0,0 +1,207 @@ +/* $Id: mcl_flid_sl.h,v 1.9 2005/01/11 13:12:28 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr) + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * This file contains headers for FLID SL congestion control module + * (Static Layer). + * See Internet Draft LCC for more informations. + */ + +#ifndef MCL_FLID_SL_H /* { */ +#define MCL_FLID_SL_H + +#ifdef FLIDS /* { */ + + +/** + * The 32 bit, ALC compliant, FLID-SL congestion control header block. + */ +typedef struct { +#ifdef _BIT_FIELDS_LTOH + UINT8 tsi:7, /* Time Slot Index (TSI) */ + trigger:1; /* Increase signal Trigger (T) */ +#else + UINT8 trigger:1, + tsi:7; +#endif + UINT8 gn; /* packet's Group Number (GN) */ + UINT16 seqno; /* packet's Sequence Number (SEQNO) */ +} flids_hdr_t; + + +/** + * FLID-SL control block. + * Contains all information required for a sending or receiving FLID-SL + * session. + */ +typedef struct { + /** + * The session state. + * 1: initial state + * 2: working state + */ + UINT8 SessionState; + + /** + * The FLID-SL Time Slot ID. + * WARNING: this is not the ALC/LCT Transport Session ID! + * WARNING: TSI must use only 7 bits. + */ + UINT8 tsi; + + /** + * The long version of the TSI. + */ + INT32 long_tsi; + + /** + * Time Slot Duration (TSD). + */ + INT32 tsd; + + /** + * For each layer, the value of the current sequence number. + */ + UINT16 tx_LayerSeq[MAX_NB_TX_LAYERS]; + + + UINT8 tx_LayerTrig[MAX_NB_TX_LAYERS]; + + /** + * For each layer, the current state. + * 1: initial state + * 2: TIMESLOT init state + * 3: working state + */ + UINT8 rx_LayerState[MAX_NB_TX_LAYERS]; + + /** + * For each layer, the Increase Trigger value. + */ + UINT8 rx_IncreaseTrigger[MAX_NB_TX_LAYERS]; + + /** + * For each layer, the following sequence number waited for. + */ + UINT16 rx_WaitFor[MAX_NB_TX_LAYERS]; + + /** + * + */ + UINT8 rx_DeafPeriod; + + /** + * + */ + UINT8 rx_CongestionDetected; + + /** + * Remaining time_count till next call to FLIDs_TxTimer function. + */ + mcl_itime_t flids_tx_timer_count; + + /** + * Deaf Period Duration in multiple of TSD + */ + UINT8 flids_deaf_period; +} flids_cb_t; + + +/* For infos about all these constants, */ +/* refer to the descriptions of the */ +/* corresponding flids_cb member variables */ + +#define FLIDS_TSD 1000000 /* TimeSlot Duration in milliseconds. */ + /* should be either 0.5, 1.0, 2.0 sec */ +#define FLIDS_DEAF_PERIOD 9 /* Deaf Period Duration in multiple of*/ + /* FLIDS_TSD */ + /* Default value: 9 seconds */ + + +/* + * FLID-SL function prototypes. + */ + +/** + * Initializes the FLID-SL congestion control mechanism for a given session. + * This must be the called before any other calls to FLID-SL functions + * @param mclcb session Control Block + */ +extern void FLIDs_InitSession (class mcl_cb *mclcb); + + +/** + * Must be called when ending a session. + * @param mclcb session Control Block + */ +extern void FLIDs_EndSession (class mcl_cb *mclcb); + + +/** + * Timer function, called periodically by the sender. + * @param mclcb session Control Block + */ +extern void FLIDs_TxTimer (class mcl_cb *mclcb); + + +/** + * Increase the Time Slot Index (TSI) periodically (the period is TSD). + * @param mclcb session Control Block + */ +extern void FLIDs_NewTimeSlot (class mcl_cb *mclcb); + +/** + * Build the FLID-SL header for each packet to send. + * @param mclcb session Control Block + * @param hdr_buff points to a buffer receiving the FLIDs header + * @param grp_idx index of the group within the set of groups used for + * that session + * @return MCL_OK (0) if success, else the corresponding error code + */ +extern int FLIDs_tx_FillHeader (class mcl_cb *mclcb, + flids_hdr_t *hdr_buff, UINT8 grp_idx); + +/** + * Analyze the packet FLID-SL header. + * @param mclcb session Control Block + * @param hdr_buff pointer to the FLID-SL header. + * @return the layer number (>=0) if success, else the error + * code as defined in mcl_error.h. + */ +extern int FLIDs_rx_AnalyzePacket (class mcl_cb *mclcb, + flids_hdr_t *hdr_buff); + +/** + * Used to set various FLID-SL options and parameters. + * @param mclcb session Control Block + * @param optname a defined option name -> FLIDS_OPT_* + * @param optvalue pointer to the value for this option. + * @param optlen size of the argument pointed by optvalue. + * @return Completion status (MCL_OK or MCL_ERROR) + */ +extern mcl_error_status FLIDs_ctl (class mcl_cb *mclcb, INT32 optname, + void *optvalue, INT32 optlen); + + +#endif /* } FLIDS */ + +#endif /* } MCL_FLID_SL_H */ diff --git a/src/alc/mcl_flute.cpp b/src/alc/mcl_flute.cpp new file mode 100644 index 0000000..2c33a84 --- /dev/null +++ b/src/alc/mcl_flute.cpp @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * Constructor. + */ +mcl_rx_flute::mcl_rx_flute () +{ + this->store_all_adus_by_default = 0; + this->desired_tois = NULL; + this->delete_current_packet = false; +} + + +/** + * Destructor. + */ +mcl_rx_flute::~mcl_rx_flute () +{ + mcl_toi_list_t *e; /* element */ + mcl_toi_list_t *ne; /* next element */ + + /* there is no way to determine precisely if in FLUTE mode or not + * since there is no mclcb pointer... So be very carefull... */ + for (e = this->desired_tois; e != NULL; e = ne) { + ne = e->next; + free(e); + } + this->desired_tois = NULL; +} + + +/** + * Set the delivery mode. + * => See header file for more informations. + */ +mcl_error_status +mcl_rx_flute::set_flute_store_all_adus_by_default + (mcl_cb *const mclcb, + bool optvalue) +{ + TRACELVL(5, (mcl_stdout, + "-> mcl_cb::set_flute_store_all_adus_by_default: %d", optvalue)) + this->store_all_adus_by_default = optvalue; + return MCL_OK; +} + + +/** + * Add a TOI to the list of TOIs requested by the FLUTE application. + */ +mcl_error_status +mcl_rx_flute::add_requested_toi (mcl_cb *const mclcb, + UINT32 toi) +{ + mcl_toi_list_t *newtoi; + + ASSERT(mclcb->is_flute_compatible()); + if ((newtoi = (mcl_toi_list_t *)malloc(sizeof(mcl_toi_list_t))) + == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_flute_add_requested_toi: ERROR, out of memory\n")) + return MCL_ERROR; + } + newtoi->toi = toi; + newtoi->next = this->desired_tois; + this->desired_tois = newtoi; + TRACELVL(5, (mcl_stdout, + "<- mcl_flute_add_requested_toi: TOI=%d added\n", toi)) + return MCL_OK; +} + + +/** + * Check if a particular TOI has been requested by the FLUTE + * application. + */ +bool +mcl_rx_flute::is_toi_requested (mcl_cb *const mclcb, + UINT32 toi) +{ + bool found = false; + mcl_toi_list_t *listloop = this->desired_tois; + + ASSERT(mclcb->is_flute_compatible()); + if (toi == 0) { + return 1; + } + while (listloop != NULL) { + if (listloop->toi == toi) { + found = true; + break; + } + listloop = listloop->next; + } + TRACELVL(5, (mcl_stdout, + "<- mcl_flute_is_toi_requested: TOI=%d is %s\n", + toi, found ? "req" : "not req")) + return found; +} + + diff --git a/src/alc/mcl_flute.h b/src/alc/mcl_flute.h new file mode 100644 index 0000000..1ae8eb2 --- /dev/null +++ b/src/alc/mcl_flute.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ +#ifndef MCL_FLUTE_H +#define MCL_FLUTE_H + + +/** + * This class provides all the required services to manage transmissions + * in FLUTE mode. + */ +class mcl_tx_flute { + +public: + /****** Public Members ************************************************/ + + /** + * Return the FDT instance ID to use for a new FDT instance. + * @return + */ + UINT32 get_next_FDT_instanceID (); + + /** + * Increment the FDT instance ID to use next time. + */ + void incr_next_FDT_instanceID (); + + /****** Public Attributes *********************************************/ + +private: + /****** Private Members ***********************************************/ + + /****** Private Attributes ********************************************/ + + /* next FDT instance ID to deliver */ + UINT32 next_FDT_instanceID; +}; + + +/** + * Linked list of desired TOIs in FLUTE compatibility mode. + */ +typedef struct mcl_toi_list { + struct mcl_toi_list *next; + UINT32 toi; +} mcl_toi_list_t; + + +/** + * This class provides all the required services to manage receptions + * in FLUTE mode. + */ +class mcl_rx_flute { + +public: + /****** Public Members ************************************************/ + + /** Constructor. */ + mcl_rx_flute (); + + /** Destructor. */ + ~mcl_rx_flute (); + + /** + * Does the receiver use a FLUTE session that stores all ADUs by + * default? + * @return boolean + */ + bool use_flute_store_all_adus_by_default (void); + + /** + * Set the ADU delivery mode to the application. + * @param mclcb + * @param mode delivery mode to set + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_flute_store_all_adus_by_default + (mcl_cb *const mclcb, + bool optvalue); + + /** + * Add a TOI to the list of TOIs requested by the FLUTE application. + * @param mclcb + * @param toi TOI + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status add_requested_toi (class mcl_cb *const mclcb, + UINT32 toi); + + /** + * Check if a particular TOI has been requested by the FLUTE + * application. + * @param mclcb + * @param toi TOI + * @return true if this TOI has been requested, false otherwise. + */ + bool is_toi_requested (class mcl_cb *const mclcb, + UINT32 toi); + + + /****** Public Attributes *********************************************/ + /* delete current packet ? */ + bool delete_current_packet; + +private: + /****** Private Members ***********************************************/ + + + /****** Private Attributes ********************************************/ + + /* Does the receiver use a FLUTE with storage of all adus by default. */ + bool store_all_adus_by_default; + + + /* list of desired TOIs in FLUTE_DELIVERY mode */ + struct mcl_toi_list *desired_tois; + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline UINT32 +mcl_tx_flute::get_next_FDT_instanceID () +{ + return this->next_FDT_instanceID; +} + +inline void +mcl_tx_flute::incr_next_FDT_instanceID () +{ + this->next_FDT_instanceID = + (this->next_FDT_instanceID + 1) % (2^24 - 1); +} + +inline bool +mcl_rx_flute::use_flute_store_all_adus_by_default () +{ + return (this->store_all_adus_by_default); +} + +#endif /* !MCL_FLUTE_H */ diff --git a/src/alc/mcl_fsm.cpp b/src/alc/mcl_fsm.cpp new file mode 100644 index 0000000..458e759 --- /dev/null +++ b/src/alc/mcl_fsm.cpp @@ -0,0 +1,398 @@ +/* $Id: mcl_fsm.cpp,v 1.7 2005/01/11 13:12:28 roca Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "mcl_includes.h" + + +/* + * SENDER's FSM (Finite State Machine) + * + * NIL + * | + * | appli issues mcl_open() + * mcl_abort() v appli issues mcl_close() + * +----------- READY --------------------------------------------+ + * | | | + * | | first ADU submission | + * | v | + * | IN_TX : send NEW_ADU; send DU | + * | | | | ^ | + * | | | | | continue to tx or wait new ADU | + * +------------+ | +-----+ | + * | | | + * | | appli issues mcl_close() and is blocked | + * | v | + * | FINISH_TO_TX : send NO_NEW_ADU; send DU | + * | | | | ^ | + * | | | | | there are DUs remaining | + * +------------+ | +-----+ | + * | | | + * | | all DUs have been tx | + * | | | + * +------------+ | +---------------------------------------------+ + * | | | + * v v v + * END : send CLOSE + * | + * | nothing else to do + * v + * CLOSED : mcl_close() returns + * | + * v + * NIL + */ + +/*static tx_states_t tx_state = TSTATE_NIL;*/ /* state in the FSM graph */ + +#define xx TSTATE_INVALID /* for clarity */ +static const mcl_tx_states next_tx_state[6/*state*/][9/*event*/] = { + /* NIL OPEN_CALLED NEW_ADU ALL_DU_SENT CLOSE_CALLED CLOSE_SENT CLOSE_RETURN ABORT RESET*/ + /* NIL */ {xx, TSTATE_READY, xx, xx, xx, xx, xx, xx, xx}, + /* READY */ {xx, xx, TSTATE_IN_TX, xx, TSTATE_END, xx, xx, TSTATE_END, TSTATE_READY}, + /* IN_TX */ {xx, xx, TSTATE_IN_TX, xx, TSTATE_FINISH_TX,xx, xx, TSTATE_END, TSTATE_READY}, +/* FINISH_TX*/ {xx, xx, xx, TSTATE_END, xx, xx, xx, TSTATE_END, TSTATE_READY}, + /* END */ {xx, xx, xx, xx, xx, TSTATE_CLOSED, xx, TSTATE_END, TSTATE_READY}, + /* CLOSED */ {xx, xx, xx, xx, xx, xx, TSTATE_NIL, TSTATE_NIL, xx} +}; +#undef xx + +/* + * RECEIVER's FSM (Finite State Machine) + * + * NIL + * | + * | appli issues mcl_open() + * v + * recv +- READY + * NO_NEW_ADU | | | | + * | | | | + * +----+ | +-------------------------------+ + * recv | | | | appli calls + * CLOSE | | | first NEW_ADU received | mcl_close() + * | | v | + * | | IN_RX : | + * | | | | | | ^ | + * | | | | | | | recv NEW_ADU; recv DU | + * +---+ | | +-----+ | + * recv | | | +--------------------------------+ + * CLOSE | | | | appli calls + * | +---+ recv NO_NEW_ADU from peer | mcl_close() + * | | | + * | v | + * | FINISH_RX : | + * | | | | | ^ | + * | | | | | | recv DU; **NB_1** | + * +----+ | | +-----+ | + * recv | | +-------------------------------+ + * CLOSE | | | appli calls + * | | all DUs have been received | mcl_close() + * | v | + * | END : | + * | | | | ^ | + * | | | | | recv DU (ignored) | + * recv +-----+ | +-----+ | + * CLOSE | | | + * v | | + * CLOSE_RX | | + * | | | + * +-------+--------------------------------+ + * | appli calls mcl_close() + * | + * v + * CLOSED : mcl_close() returns + * | + * v + * NIL + * + * State END: + * we have received everything and the sender will not send any new ADU + * we may still receive (duplicated) DUs but we can stop at any time + * this is the normal (almost) final state when everything is ok + * + * NB_1: + * in FINISH_RX state, in FLUTE mode and in aggregated objects mode, + * the reception of new FDT instance IDs (similarly new MOID), ie. for + * TOI==0, is possible even if the FINISH_RX state traditionally + * prevents it. This is managed by the callee (who does not call the + * FSM update function), not by the present FSM update funtion itself. + */ + +/*static rx_states_t rx_state = RSTATE_NIL;*/ /* state in the FSM graph */ + +#define xx RSTATE_INVALID /* for clarity */ +static const mcl_rx_states next_rx_state[7/*state*/][9/*event*/] = { + /* NIL, OPEN_CALLED NEW_ADU NO_NEW_ADU DU_RECV ALL_DU_RECV CLOSE_CALLED CLOSE_RECV CLOSE_RETURN*/ + /* NIL */ {xx, RSTATE_READY, xx, xx, xx, xx, xx, xx, xx}, + /* READY */ {xx, xx, RSTATE_IN_RX, RSTATE_FINISH_RX,xx, xx, RSTATE_CLOSED, RSTATE_CLOSE_RX,xx}, + /* IN_RX */ {xx, xx, RSTATE_IN_RX, RSTATE_FINISH_RX,RSTATE_IN_RX, xx, RSTATE_CLOSED, RSTATE_CLOSE_RX,xx}, +/* FINISH_RX*/ {xx, xx, xx, RSTATE_FINISH_RX,RSTATE_FINISH_RX,RSTATE_END, RSTATE_CLOSED, RSTATE_CLOSE_RX,xx}, + /* END */ {xx, xx, xx, RSTATE_END, RSTATE_END, xx, RSTATE_CLOSED, RSTATE_CLOSE_RX,xx}, + /*CLOSE_RX*/ {xx, xx, xx, xx, xx, xx, RSTATE_CLOSED, RSTATE_CLOSE_RX, RSTATE_NIL}, + /* CLOSED */ {xx, xx, xx, xx, xx, xx, xx, RSTATE_CLOSED, RSTATE_NIL} +}; +#undef xx + + +/* + * strings for debug + */ +static const char * tx_states_msg[] = { + "TSTATE_NIL", + "TSTATE_READY", + "TSTATE_IN_TX", + "TSTATE_FINISH_TX", + "TSTATE_END", + "TSTATE_CLOSED", + "*INVALID*"}; + +static const char * tx_events_msg[] = { + "TEVENT_NIL", + "TEVENT_OPEN_CALLED", + "TEVENT_NEW_ADU", + "TEVENT_ALL_DU_SENT", + "TEVENT_CLOSE_CALLED", + "TEVENT_CLOSE_SENT", + "TEVENT_CLOSE_RETURN", + "TEVENT_ABORT", + "TEVENT_RESET"}; + +static const char * rx_states_msg[] = { + "RSTATE_NIL", + "RSTATE_READY", + "RSTATE_IN_RX", + "RSTATE_FINISH_RX", + "RSTATE_END", + "RSTATE_CLOSE_RX", + "RSTATE_CLOSED", + "*INVALID*"}; + +static const char * rx_events_msg[] = { + "REVENT_NIL", + "REVENT_OPEN_CALLED", + "REVENT_NEW_ADU", + "REVENT_NO_NEW_ADU", + "REVENT_DU_RECV", + "REVENT_ALL_DU_RECV", + "REVENT_CLOSE_CALLED", + "REVENT_CLOSE_RECV", + "REVENT_CLOSE_RETURN", + "REVENT_RESET"}; + + +mcl_fsm::mcl_fsm () +{ + this->tx_state = TSTATE_NIL; + this->rx_state = RSTATE_NIL; +} + + +mcl_fsm::~mcl_fsm () +{ + this->tx_state = TSTATE_NIL; + this->rx_state = RSTATE_NIL; +} + + +void +mcl_fsm::update_tx_state (mcl_cb *const mclcb, mcl_tx_events event) +{ + mcl_tx_states new_state; + + TRACELVL(5, (mcl_stdout, "-> mcl_fsm::update_tx_state: event=%s\n", + this->print_tx_event(mclcb, event))) + ASSERT (event >= TEVENT_OPEN_CALLED && event <= TEVENT_RESET); + new_state = next_tx_state[this->tx_state][event]; + if (new_state == TSTATE_INVALID) { + PRINT_ERR((mcl_stderr, + "mcl_fsm::update_tx_state: ERROR, event %s invalid in state %s\n", + this->print_tx_event(mclcb, event), + this->print_tx_state(mclcb))) + mcl_exit(1); + } + this->tx_state = new_state; + TRACELVL(5, (mcl_stdout, "<- mcl_fsm::update_tx_state: new_state %s\n", + this->print_tx_state(mclcb))) +} + + +void +mcl_fsm::update_rx_state (class mcl_cb *const mclcb, mcl_rx_events event) +{ + mcl_rx_states new_state; + + TRACELVL(5, (mcl_stdout, "-> mcl_fsm::update_rx_state: event=%s\n", + this->print_rx_event(mclcb, event))) + ASSERT (event >= REVENT_OPEN_CALLED && event <= REVENT_CLOSE_RETURN); + new_state = next_rx_state[this->rx_state][event]; + if (new_state == RSTATE_INVALID) { + PRINT_ERR((mcl_stderr, + "mcl_fsm::update_rx_state: ERROR, event %s invalid in state %s\n", + this->print_rx_event(mclcb, event), + this->print_rx_state(mclcb))) + mcl_exit(1); + } + this->rx_state = new_state; + TRACELVL(5, (mcl_stdout, "<- mcl_fsm::update_rx_state: new_state %s\n", + this->print_rx_state(mclcb))) +} + + +const char * +mcl_fsm::print_tx_state (class mcl_cb *const mclcb) const +{ + ASSERT(this->tx_state >= TSTATE_NIL && this->tx_state <= TSTATE_INVALID); + return tx_states_msg[this->tx_state]; + +} + + +const char * +mcl_fsm::print_rx_state (class mcl_cb *const mclcb) const +{ + ASSERT(this->rx_state >= RSTATE_NIL && this->rx_state <= RSTATE_INVALID); + return rx_states_msg[this->rx_state]; +} + + +const char * +mcl_fsm::print_tx_event (class mcl_cb *const mclcb, mcl_tx_events event) const +{ + ASSERT(event >= TEVENT_NIL && event <= TEVENT_RESET); + return tx_events_msg[event]; + +} + + +const char * +mcl_fsm::print_rx_event (class mcl_cb *const mclcb, mcl_rx_events event) const +{ + ASSERT(event >= REVENT_NIL && event <= REVENT_CLOSE_RETURN); + return rx_events_msg[event]; +} + + +bool +mcl_fsm::is_opened (mcl_cb *const mclcb) const +{ + if (mclcb->is_a_sender()) { + return (this->tx_state >= TSTATE_READY); + } else if (mclcb->is_a_receiver()) { + return (this->rx_state >= RSTATE_READY); + } + mcl_exit(-1); // impossible, unsupported mode + return false; // to avoid warning +} + + +bool +mcl_fsm::can_send_data (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_sender()); + return (this->tx_state == TSTATE_IN_TX || + this->tx_state == TSTATE_FINISH_TX); +} + + +bool +mcl_fsm::can_recv_data (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_receiver()); + return (this->rx_state == RSTATE_READY || /* req to wait for 1st NEW_ADU */ + this->rx_state == RSTATE_IN_RX || + this->rx_state == RSTATE_FINISH_RX); +} + + +#if 0 +bool +mcl_fsm::finish_tx (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_sender()); + return(this->tx_state == TSTATE_FINISH_TX); +} +#endif + + +bool +mcl_fsm::no_new_adu (mcl_cb *const mclcb) const +{ + if (mclcb->is_a_sender()) { + return (this->tx_state == TSTATE_FINISH_TX || + this->tx_state == TSTATE_END || + this->tx_state == TSTATE_CLOSED); + } else if (mclcb->is_a_receiver()) { + return (this->rx_state == RSTATE_FINISH_RX || + this->rx_state == RSTATE_END || + this->rx_state == RSTATE_CLOSE_RX || + this->rx_state == RSTATE_CLOSED); + } + mcl_exit(-1); // impossible, unsupported mode + return false; // to avoid warning +} + + +bool +mcl_fsm::no_new_undup_du (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_receiver()); + return (this->rx_state == RSTATE_END || + this->rx_state == RSTATE_CLOSE_RX || + this->rx_state == RSTATE_CLOSED); +} + + +bool +mcl_fsm::close_already_rx (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_receiver()); + return (this->rx_state == RSTATE_CLOSE_RX || + this->rx_state == RSTATE_CLOSED); +} + + +bool +mcl_fsm::close_can_return (mcl_cb *const mclcb) const +{ + if (mclcb->is_a_sender()) { + return (this->tx_state == TSTATE_CLOSED); + } else if (mclcb->is_a_receiver()) { + return (this->rx_state == RSTATE_CLOSED); + } + mcl_exit(-1); // impossible, unsupported mode + return false; // to avoid warning +} + + +bool +mcl_fsm::is_closed (mcl_cb *const mclcb) const +{ + if (mclcb->is_a_sender()) { + return (this->tx_state == TSTATE_CLOSED || + this->tx_state == TSTATE_NIL); + } else if (mclcb->is_a_receiver()) { + return (this->rx_state == RSTATE_CLOSED || + this->rx_state == RSTATE_NIL); + } + mcl_exit(-1); // impossible, unsupported mode + return false; // to avoid warning +} + diff --git a/src/alc/mcl_fsm.h b/src/alc/mcl_fsm.h new file mode 100644 index 0000000..9a9d6a0 --- /dev/null +++ b/src/alc/mcl_fsm.h @@ -0,0 +1,231 @@ +/* $Id: mcl_fsm.h,v 1.4 2005/01/11 13:12:28 roca Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_FSM_H /* { */ +#define MCL_FSM_H + +/* + * SENDER's FSM (Finite State Machine) + */ + +enum mcl_tx_states { + TSTATE_NIL = 0, + TSTATE_READY, + TSTATE_IN_TX, + TSTATE_FINISH_TX, + TSTATE_END, + TSTATE_CLOSED, + TSTATE_INVALID +}; + +enum mcl_tx_events { + TEVENT_NIL = 0, + TEVENT_OPEN_CALLED, /* application has called mcl_open */ + TEVENT_NEW_ADU, /* tx: mcl_send called, rx: NEW ADU received */ + TEVENT_ALL_DU_SENT, /* all the DUs have been sent */ + TEVENT_CLOSE_CALLED, /* application has called mcl_close */ + TEVENT_CLOSE_SENT, /* CLOSE sent to peer */ + TEVENT_CLOSE_RETURN, /* mcl_close just returned */ + TEVENT_ABORT, /* mcl_abort called */ + TEVENT_RESET /* mcl_abort called */ +}; + + +/* + * RECEIVER's FSM (Finite State Machine) + */ + +enum mcl_rx_states { + RSTATE_NIL = 0, + RSTATE_READY, + RSTATE_IN_RX, + RSTATE_FINISH_RX, + RSTATE_END, + RSTATE_CLOSE_RX, /* CLOSE has been received */ + RSTATE_CLOSED, + RSTATE_INVALID +}; + +enum mcl_rx_events { + REVENT_NIL = 0, + REVENT_OPEN_CALLED, /* application has called mcl_open */ + REVENT_NEW_ADU, /* NEW_ADU received */ + REVENT_NO_NEW_ADU, /* NO_NEW_ADU received */ + REVENT_DU_RECV, /* DU received */ + REVENT_ALL_DU_RECV, /* all the DUs have been received */ + REVENT_CLOSE_CALLED, /* application has called mcl_close */ + REVENT_CLOSE_RECV, /* CLOSE sent to peer */ + REVENT_CLOSE_RETURN /* mcl_close just returned */ +}; + + +/** + * Class defining the Finite state machine of either a sender or a receiver. + */ +class mcl_fsm { + +public: + /****** Public Members ************************************************/ + /** Default constructor. */ + mcl_fsm (); + + /** Default destructor. */ + ~mcl_fsm (); + + /** + * Update the current tx (resp. rx) state with a new event. + * @param mclcb + * @param event new tx (resp. rx) event + * @return returns nothing but calls exit in case of invalid + * transition + */ + void update_tx_state (class mcl_cb *const mclcb, mcl_tx_events event); + void update_rx_state (class mcl_cb *const mclcb, mcl_rx_events event); + /** + * Get current state. + * @param mclcb + * @return State + */ + mcl_tx_states get_tx_state (class mcl_cb *const mclcb) const; + mcl_rx_states get_rx_state (class mcl_cb *const mclcb) const; + + /** + * Create a string for the current state. + * The buffer containing the string is statically allocated in + * the mcl_fsm class. Do not free it! + * @param mclcb + * @return String + */ + const char *print_tx_state (class mcl_cb *const mclcb) const; + const char *print_rx_state (class mcl_cb *const mclcb) const; + + /** + * Create a string for the event. + * The buffer containing the string is statically allocated in + * the mcl_fsm class. Do not free it! + * @param mclcb + * @param event tx (resp. rx) event to print + * @return String + */ + const char *print_tx_event (class mcl_cb *const mclcb, mcl_tx_events event) const; + const char *print_rx_event (class mcl_cb *const mclcb, mcl_rx_events event) const; + + /** + * Is the session (SENDER or RECEIVER) created, i.e. mcl_open() called? + * @param mclcb + * @return boolean + */ + bool is_opened (mcl_cb *const mclcb) const; + + /** + * Can we send data on this session? + * @param mclcb + * @return boolean + */ + bool can_send_data (mcl_cb *const mclcb) const; + + /** + * Is the receiver in a state where data can be received? + * Receiver specific function. + * @param mclcb + * @return boolean + */ + bool can_recv_data (mcl_cb *const mclcb) const; + +#if 0 + /** + * Are we in FINISH_TX state? + * Sender specific function. + * @param mclcb + * @return boolean + */ + bool finish_tx (mcl_cb *const mclcb) const; +#endif + + /** + * Do we expect new ADUs or not? + * Sender and receiver function. + * @param mclcb + * @return boolean + */ + bool no_new_adu (mcl_cb *const mclcb) const; + + /** + * Do we expect new DUs or do we have everything we need? + * Receiver specific function. + * @param mclcb + * @return boolean + */ + bool no_new_undup_du (mcl_cb *const mclcb) const; + + /** + * Did we already receive a CLOSE sig from the source or did we + * already receive all the expected DUs and appli issued a close()? + * If yes, then we can ignore a new CLOSE sig. + * Receiver specific function. + * @param mclcb + * @return boolean + */ + bool close_already_rx (mcl_cb *const mclcb) const; + + /** + * Should a call to mcl_close() return control to the application? + * Sender and receiver function. + * @param mclcb + * @return boolean + */ + bool close_can_return (mcl_cb *const mclcb) const; + + /** + * Is the session (SENDER or RECEIVER) closed? + * @param mclcb + * @return boolean + */ + bool is_closed (mcl_cb *const mclcb) const; + + /****** Public Attributes *********************************************/ + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + mcl_tx_states tx_state; + mcl_rx_states rx_state; + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline mcl_tx_states +mcl_fsm::get_tx_state (class mcl_cb *const mclcb) const +{ + return this->tx_state; +} + +inline mcl_rx_states +mcl_fsm::get_rx_state (class mcl_cb *const mclcb) const +{ + return this->rx_state; +} + +#endif /* } MCL_FSM_H */ diff --git a/src/alc/mcl_includes.h b/src/alc/mcl_includes.h new file mode 100644 index 0000000..2770ec2 --- /dev/null +++ b/src/alc/mcl_includes.h @@ -0,0 +1,163 @@ +/* $Id: mcl_includes.h,v 1.22 2005/05/24 10:37:57 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_INCLUDES_H /* { */ +#define MCL_INCLUDES_H + +#ifdef SOLARIS +#define __EXTENSIONS__ /* XXX: we have pbs without on Solaris 2.5.1 */ +#endif + +/****** System includes *******************************************************/ + +#include +#include +#include +using namespace std; + +#include +#ifndef WIN32 +extern int errno; +#endif /* OS */ +#include +#include +#include +#include +#include +#include +#include + +#ifndef FREEBSD +#include +#endif +#include + + +/* + * OS dependant includes + */ +#ifdef WIN32 /* { WIN32 */ + +#include +#include +#include +#include + +#include /* ADDED */ +#include /* ADDED */ +#include /* ADDED */ +#include /* ADDED */ +#include /* ADDED */ + + +#else /* } UNIX Systems { */ + +#include + +#ifndef FREEBSD +#include /* for MAXINT */ +#endif + +#include +#include +#include +#include +#include +#if defined(SOLARIS) || defined(FREEBSD) || defined(HPUX) || defined(IRIX) +#include +#endif /* SOLARIS || FREEBSD */ +#if defined(SOLARIS) +#include +#endif /* SOLARIS */ +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* } OS */ + + +/****** MCL includes **********************************************************/ + + +#include "../common/mcl_types.h" // First: define portable data types +#include "../common/mcl_osdep.h" // Second: OS specific defines +#include "mcl_profile.h" // Third: MCL-ALC default profile +#include "../common/mcl_defines.h" // Fourth: major defines/constants +#include "../common/mcl_lib_api.h" +#include "../common/mcl_version.h" +#include "../common/mcl_addr.h" +#include "../common/ssm_for_linux.h" +#include "../common/mcl_socket_lib.h" +#include "../common/mcl_debug.h" +#include "../common/mcl_itime.h" +#include "../common/mcl_blocking_struct.h" +#include "../common/mcl_periodic_timer.h" +#include "../common/mcl_file_io.h" + +#include "mcl.h" /* general purpose MCL constants */ +#include "mcl_error.h" + +#ifdef RSE_FEC +#include "../common/rse_fec.h" +#endif +#ifdef LDPC_FEC +#include "../../../ldpc/src/ldpc_fec.h" +#endif + +#include "mcl_lib.h" +#include "mcl_data.h" +#ifdef VIRTUAL_TX_MEM +#include "mcl_vtmem.h" +#endif +#ifdef VIRTUAL_RX_MEM +#include "mcl_vrmem.h" +#endif +#include "mcl_rx_storage.h" + +#include "mcl_tx_tab.h" +#include "mcl_rlc.h" +#include "mcl_flid_sl.h" + +#include "mcl_socket.h" +#include "mcl_periodic_proc.h" +#include "mcl_lct_hdr.h" +#include "mcl_alc_hdr.h" +#include "mcl_stats.h" +#include "mcl_fsm.h" +#include "mcl_proto.h" +#include "mcl_rx.h" +#include "mcl_rx_window.h" +#include "mcl_flute.h" +#include "mcl_tx.h" +#include "mcl_cb.h" +#include "mcl_fec.h" + +#ifdef METAOBJECT_USED +#include "mcl_meta_object.h" +#include "mcl_meta_object_layer.h" +#endif + +#endif /* } MCL_INCLUDES_H */ diff --git a/src/alc/mcl_layer.cpp b/src/alc/mcl_layer.cpp new file mode 100644 index 0000000..97b1a29 --- /dev/null +++ b/src/alc/mcl_layer.cpp @@ -0,0 +1,424 @@ +/* $Id: mcl_layer.cpp,v 1.17 2005/05/24 10:37:57 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * Layer management functions. + */ + +#include "mcl_includes.h" + +/* + * init the number of layers as required + */ +#ifdef SVSOA_RECV +int +mcl_init_layer_nb (mcl_cb *mclcb, + int nb_lay) +#else +int +mcl_init_layer_nb (mcl_cb *mclcb) +#endif +{ + TRACELVL(5, (mcl_stdout, "-> mcl_init_layer_nb:\n")) + ASSERT(mclcb->max_nb_layers <= MAX_NB_TX_LAYERS); + if (mclcb->is_a_receiver()) { +#ifdef SVSOA_RECV + /* use immediately the number of layers specified */ + mclcb->nb_layers = nb_lay; +#else + /* only 1 layer */ + mclcb->nb_layers = 1; +#endif + } else { + ASSERT(mclcb->is_a_sender()); + mclcb->nb_layers = mclcb->max_nb_layers; + } + TRACELVL(5, (mcl_stdout, + "<- mcl_init_layer_nb: (%s) nb_layers=%d, max_nb_layers=%d\n", + (mclcb->is_a_receiver() ? "receiver" : "sender"), + mclcb->nb_layers, mclcb->max_nb_layers)) + return 0; +} + + +/* + * Create all the required sockets and initialize them. + * Used both for sender and receiver, and unicast or multicast. + * @param mclcb + * @return Return 0 if ok, < 0 if error. + */ +mcl_error_status +mcl_init_layer_sockets (mcl_cb *mclcb) +{ + int layer; + mcl_socket *so; + //struct sockaddr_in saddr; + mcl_addr addr; /* temp session addr for each layer */ + + TRACELVL(5, (mcl_stdout, "-> mcl_init_layer_sockets:\n")) + + //for (layer = 0, so = mclcb->socket_tab; layer < mclcb->mcl_max_group; + for (layer = 0, so = mclcb->socket_tab; layer < mclcb->max_nb_layers; + layer++, so++) { + addr = mclcb->addr; + if (addr.is_multicast_addr()) { + /* + * if we are a receiver, subscribe only to the + * groups of interest and skip the others... + */ + if (mclcb->is_a_receiver() && + (layer >= mclcb->nb_layers)) { + continue; + } + /* use a block of mcast addr... */ + addr.incr_addr(layer); + /* changing the port number is required to make + * sure packets are delivered to the right socket */ + addr.incr_port(layer); + } else { + /* this is unicast, so a single socket is sufficient */ + if (layer >= 1) { + continue; + } + } + /* + * init everything + */ + if (mclcb->is_a_sender()) { + if (so->init_as_sender(mclcb, layer, &addr, + mclcb->mcast_if_addr, + mclcb->mcast_if_name) == MCL_ERROR) { + TRACELVL(5, (mcl_stdout, "<- mcl_init_layer_sockets: ERROR\n")) + return MCL_ERROR; + } + } else { + ASSERT(mclcb->is_a_receiver()); + if (so->init_as_receiver(mclcb, layer, &addr, +#ifdef SSM + &(mclcb->rx.src_addr), +#endif + mclcb->mcast_if_addr, + mclcb->mcast_if_name) == MCL_ERROR) { + TRACELVL(5, (mcl_stdout, "<- mcl_init_layer_sockets: ERROR\n")) + return MCL_ERROR; + } + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_init_layer_sockets:\n")) + return MCL_OK; +} + + +/* + * add the specified layer or highest layer if layer is MCL_HIGHEST_LAYER + * returns 0 if OK, < 0 if error + */ +int +mcl_add_layer (mcl_cb *mclcb, + int layer) +{ + //struct sockaddr_in saddr; + mcl_addr addr; + + TRACELVL(5, (mcl_stdout, "-> mcl_add_layer: %d\n", layer)) + if (layer == MCL_HIGHEST_LAYER) + layer = mclcb->nb_layers; + if (layer != mclcb->nb_layers) { + /* cumulative scheme so do not allow gaps in layers */ + goto bad; + } + if (mclcb->nb_layers + 1 > mclcb->max_nb_layers) { + /* we have reached the maximum nb of layer */ + goto bad; + } + if (mclcb->ucast_mcast_mode & MODE_MCAST_RX) { + /* only with multicast */ + ASSERT(mclcb->addr.is_multicast_addr()); + addr = mclcb->addr; + addr.incr_addr(layer); + /* changing the port number is in fact only required + * by Solaris, not by Linux! */ + addr.set_port(addr.get_port() + layer); + /* + * now init everything + */ + if (mclcb->socket_tab[layer].init_as_receiver(mclcb, layer, + &addr, +#ifdef SSM + &(mclcb->rx.src_addr), +#endif + mclcb->mcast_if_addr, + mclcb->mcast_if_name) == MCL_ERROR) { + TRACELVL(5, (mcl_stdout, "<- mcl_init_layer_sockets: ERROR\n")) + return MCL_ERROR; + } + } + mclcb->nb_layers++; + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tadd_layer %d\n", + time.tv_sec, time.tv_usec, layer)) + } + TRACELVL(5, (mcl_stdout, "<- mcl_add_layer: new nb_layer=%d\n", mclcb->nb_layers)) + return 0; + +bad: + if (mclcb->get_verbosity() >= 4) + PRINT_ERR((mcl_stderr, "mcl_add_layer: ERROR, can't add layer %d\n", + layer)) + TRACELVL(5, (mcl_stdout, "<- mcl_add_layer: ERROR\n")) + return -1; +} + + +/* + * drop the specified layer or highest layer if layer is MCL_HIGHEST_LAYER + * after unsubscribing to multicast group + * returns 0 if OK, < 0 if error + * It is possible to call it in "check" mode just to see if dropping + * would be possible... + * + * TO DO: case where multiple layer -> single socket + */ +int +mcl_drop_layer (mcl_cb *mclcb, + int layer, /* layer to drop */ + int check) /* MCL_CHECK_ONLY if check w/o */ + /* dropping MCL_DO_IT otherwise */ +{ + TRACELVL(5, (mcl_stdout, "-> mcl_drop_layer: layer=%d\n", layer)) + if (mclcb->nb_layers <= 0) { + /* already done, return */ + TRACELVL(5, (mcl_stdout, " mcl_drop_layer: already dropped\n")) + goto ok; + } + if (layer == MCL_ALL_LAYERS) { + /* drop everything, including layer 0 if possible */ + while (mclcb->nb_layers > 1) { + mcl_drop_layer(mclcb, MCL_HIGHEST_LAYER, + MCL_DO_IT); + } + ASSERT(mclcb->nb_layers == 1); + if (!mclcb->rx.never_leave_base_layer) + mcl_drop_this_layer(mclcb, 0); /* and layer 0 */ + goto ok; + } else if (layer == MCL_HIGHEST_LAYER) { + layer = mclcb->nb_layers - 1; + } else if (layer != mclcb->nb_layers - 1) { + /* this is a cumulative scheme */ + /* => can only drop highest layer */ + goto bad; + } + if (layer <= 0) { + /* can't drop layer 0, no matter wether */ + /* never_leave_base_layer is set or not */ + goto bad; + } + if (check == MCL_CHECK_ONLY) { + TRACELVL(5, (mcl_stdout, "<- mcl_drop_layer: drop possible\n")) + return 0; /* do nothing */ + } + /* ok, possible so drop it */ + mcl_drop_this_layer(mclcb, layer); +ok: + TRACELVL(5, (mcl_stdout, "<- mcl_drop_layer:\n")) + return 0; + +bad: + if (mclcb->get_verbosity() >= 4) + PRINT_ERR((mcl_stderr, "mcl_drop_layer: ERROR cant drop layer %d\n", + layer)) + TRACELVL(5, (mcl_stdout, "<- mcl_drop_layer: ERROR\n")) + return -1; +} + + +/* + * same as mcl_drop_layer except that there is no check (which enables + * to drop layer 0!). Use with care... + */ +int +mcl_drop_this_layer (mcl_cb *mclcb, + int layer) /* layer to drop */ +{ + mcl_socket *so; + mcl_addr addr; + + TRACELVL(5, (mcl_stdout, "-> mcl_drop_this_layer: layer=%d\n", layer)) + mclcb->nb_layers--; + /* close the socket but do not free anything (call reset for that) */ + so = &(mclcb->socket_tab[layer]); + so->close_sockets(mclcb); +#if 0 + if (mclcb->ucast_mcast_mode & MODE_MCAST_RX) { + /* + * drop multicast group first... + * NB: check consistency with mcl_layer_sock_init() + */ + struct ip_mreq imr; + + mg = &(mclcb->socket_tab[layer]); +#if 0 + imr.imr_multiaddr.s_addr = mg->saddr.sin_addr.s_addr; + imr.imr_interface.s_addr = htonl(mclcb->mcast_if); +#endif + imr.imr_multiaddr.s_addr = htonl(mg->addr.get_addr()); + imr.imr_interface.s_addr = htonl(mclcb->mcast_if.get_addr()); + if (setsockopt(mg->ses_sock, IPPROTO_IP, IP_DROP_MEMBERSHIP, + (char *)&imr, sizeof(imr)) < 0) { + perror("mcl_drop_this_layer: IP_DROP_MEMBERSHIP"); + mcl_exit(1); + } + if (mg->can_rx()) { + /* remove from select() */ + FD_CLR((u_int) mg->ses_sock, &(mclcb->rxlvl.fds)); + if (mclcb->rxlvl.nfds == (int)mg->ses_sock + 1) /* TODO WIN32 compliant? */ + mclcb->rxlvl.nfds--; + mclcb->rxlvl.n_fd--; + } + mg->can_rx = mg->can_tx = 0; + + if (mcl_is_valid_sock(mg->ses_sock)) { +#ifdef WIN32 + closesocket(mg->ses_sock); + mg->ses_sock = INVALID_SOCKET; +#else /* UNIX */ + close(mg->ses_sock); + mg->ses_sock = 0; +#endif + } + if (mcl_is_valid_sock(mg->priv_sock)) { +#ifdef WIN32 + closesocket(mg->priv_sock); + mg->priv_sock = INVALID_SOCKET; +#else /* UNIX */ + close(mg->priv_sock); + mg->priv_sock = 0; +#endif + } + memset(mg, 0, sizeof(*mg)); + } else if ((mclcb->ucast_mcast_mode & MODE_UNI_RX) && layer == 0) { + /* + * we are a unicast rx... + * do nothing (layering is only simulated) except if + * layer 0 is dropped in which case we close everything! + */ + ASSERT(!(mclcb->ucast_mcast_mode & MODE_MCAST_RX)); + mg = &(mclcb->socket_tab[0]); + if (mg->can_rx) { + /* remove from select() */ + FD_CLR((u_int) mg->ses_sock, &(mclcb->rxlvl.fds)); + if (mclcb->rxlvl.nfds == (int)mg->ses_sock + 1) /* TODO WIN32 compliant? */ + mclcb->rxlvl.nfds--; + mclcb->rxlvl.n_fd--; + } + mg->can_rx = mg->can_tx = 0; + + if (mcl_is_valid_sock(mg->ses_sock)) { +#ifdef WIN32 + closesocket(mg->ses_sock); + mg->ses_sock = INVALID_SOCKET; +#else /* UNIX */ + close(mg->ses_sock); + mg->ses_sock = 0; +#endif + } + if (mcl_is_valid_sock(mg->priv_sock)) { +#ifdef WIN32 + closesocket(mg->priv_sock); + mg->priv_sock = INVALID_SOCKET; +#else /* UNIX */ + close(mg->priv_sock); + mg->priv_sock = 0; +#endif + } + memset(mg, 0, sizeof(*mg)); + } else if ((mclcb->ucast_mcast_mode & MODE_MCAST_TX) || + ((mclcb->ucast_mcast_mode & MODE_UNI_TX) && layer == 0)) { + /* + * we are a source... + * just close the sending socket (there is no session fd) + */ + mg = &(mclcb->socket_tab[layer]); + ASSERT(!mg->ses_sock); + if (mcl_is_valid_sock(mg->priv_sock)) { +#ifdef WIN32 + closesocket(mg->priv_sock); + mg->priv_sock = INVALID_SOCKET; +#else /* UNIX */ + close(mg->priv_sock); + mg->priv_sock = 0; +#endif + } + } +#endif + + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tdrop_layer %d\n", + time.tv_sec, time.tv_usec, layer)) + } + TRACELVL(5, (mcl_stdout, "<- mcl_drop_this_layer: new nb_lvl=%d\n", + mclcb->nb_layers)) + return 0; +} + + +/* + * Free all the layers and associated sockets. + * Used both for sender and receiver, and unicast or multicast. + * Return 0 if ok, < 0 if error. + */ +int +mcl_free_all_layers (mcl_cb *const mclcb) +{ + INT32 i; + mcl_socket *so; + + TRACELVL(5, (mcl_stdout, "-> mcl_close_sockets:\n")) + if (mclcb->is_a_receiver()) { + /* + * we are above all a receiver. Use the dedicated function... + */ + mcl_drop_layer(mclcb, MCL_ALL_LAYERS, MCL_DO_IT); + } else { + /* + * we are above all a sender. Go through all socket entries... + */ + for (i = 0, so= mclcb->socket_tab; i < mclcb->mcl_max_group; + i++, so++) { + if (!mclcb->addr.is_multicast_addr() && i > 0) { + /* + * there are several socket entries but send + * only on one socket ! + */ + continue; + } + /* now close it */ + mcl_drop_this_layer(mclcb, i); + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_close_sockets:\n")) + return 0; +} + diff --git a/src/alc/mcl_lct_hdr.cpp b/src/alc/mcl_lct_hdr.cpp new file mode 100644 index 0000000..e97cdbb --- /dev/null +++ b/src/alc/mcl_lct_hdr.cpp @@ -0,0 +1,781 @@ +/* $Id: mcl_lct_hdr.cpp,v 1.28 2005/01/11 13:12:29 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/* + * private functions + */ +/* sending side */ +static int lct_hdr_add_FTI_he (mcl_cb *mclcb, char *ptr, int hlen, + hdr_infos_t *hdr_infos); +static int lct_hdr_add_NONEWADU_he (mcl_cb *mclcb, char *ptr, int hlen, + hdr_infos_t *hdr_infos); + +static int lct_hdr_add_FDT_he (mcl_cb *mclcb, char *ptr, int hlen, + hdr_infos_t *hdr_infos); +#ifdef METAOBJECT_USED +static int lct_hdr_add_MODT_he (mcl_cb *mclcb, char *ptr, int hlen, + hdr_infos_t *hdr_infos); +#endif + +/* receiving side */ +static int lct_hdr_parse_he (mcl_cb *mclcb, char *ptr, int hlen, + hdr_infos_t *hdr_infos); + + +/****** sending side **********************************************************/ + +/** + * Initializes the LCT header (fixed header plus common fields). + * Assumes that the memory block has been allocated by the caller + * who MUST ensure that it will be large enough to hold all the + * possible fields! + * Returns the size of the LCT header (bytes), -1 if error. + */ +int +lct_hdr_create (mcl_cb *mclcb, + fixed_lct_hdr_t *lct_hdr, + hdr_infos_t *hdr_infos) +{ + INT32 hlen; /* length of fixed+variable LCT hdr (bytes) */ + UINT32 word1; + + TRACELVL(5, (mcl_stdout, "-> lct_hdr_create:\n")) + /* + * fixed size LCT header part + */ + *(UINT32*)lct_hdr = 0; /* reset all flags */ + lct_hdr->version= LCT_VERSION; + //lct_hdr->flag_c = 0; /* no CC extension */ + //lct_hdr->reserved = 0; + //lct_hdr->flag_h = 0; /* no half word format by default */ + //lct_hdr->flag_s = 0; /* no TSI field by default */ + //lct_hdr->flag_o = 0; /* no TOI field by default */ + //lct_hdr->flag_t = 0; /* no SCT field by default */ + //lct_hdr->flag_r = 0; /* no ERT field by default */ + lct_hdr->flag_a = (hdr_infos->close == true) ? 1 : 0; + //lct_hdr->flag_b = 0; /* no object close by default */ + lct_hdr->codepoint = hdr_infos->fec_encoding_id; + /* NB: the FPI field is added by ALC if required ! */ + /* + * hlen (total header len) is different from lct_hdr->hdr_len + * (which only includes the header variable size part) + */ + hlen = sizeof(fixed_lct_hdr_t); /* includes 32bit CCI field */ + ASSERT(!lct_hdr->flag_c); /* no additional CCI extension */ + /* + * additional fields + */ + if (((hdr_infos->demux_label & 0xFFFF0000) == 0) && + (hdr_infos->TOI_present && ((hdr_infos->idf_adu & 0xFFFF0000) == 0))) { + /* + * use compact half word format since neither the TSI nor the + * TOI (when present) exceed 16 bits + */ + lct_hdr->flag_h = 1; /* half word */ + word1 = ((UINT16)hdr_infos->demux_label << 16) | + (UINT16)hdr_infos->idf_adu; + *(UINT32*)((char*)lct_hdr + hlen) = htonl(word1); + hlen += 4; + } else { + /* add a 32 bit TSI (transport session idf) */ + lct_hdr->flag_s = 1; + *(UINT32*)((char*)lct_hdr + hlen) = + htonl(hdr_infos->demux_label); + hlen += 4; + if (hdr_infos->TOI_present) { + /* add a 32 bit TOI (transport object idf) */ + lct_hdr->flag_o = 1; /* 32 bits */ + *(UINT32*)((char*)lct_hdr + hlen) = + htonl(hdr_infos->idf_adu); + hlen += 4; + } + } +#if 0 + if (hdr_infos->demux_label) { + /* add transport session idf (previously called demux_label) */ + lct_hdr->flag_s = 1; + *(UINT32*)((char*)lct_hdr + hlen) = + htonl(hdr_infos->demux_label); + hlen += 4; + } + /* add a 32 bits TOI (tx object idf) */ + lct_hdr->flag_o = 1; /* 32 bits */ + *(UINT32*)((char*)lct_hdr + hlen) = htonl(hdr_infos->idf_adu); + hlen += 4; +#endif + /* + * add header extensions if any + */ + if (hdr_infos->FTI_present) { + /* add an FTI extension */ + ASSERT(hdr_infos->adu_len > 0); + hlen = lct_hdr_add_FTI_he(mclcb,(char*)lct_hdr, hlen, hdr_infos); + if (hlen < 0) goto bad; + } + if (hdr_infos->FDT_present) { + /* add an FDT extension */ + hlen = lct_hdr_add_FDT_he(mclcb,(char*)lct_hdr, hlen, hdr_infos); + if (hlen < 0) goto bad; + } +#ifdef METAOBJECT_USED + if (hdr_infos->MODT_present) { + /* add an MODT extension */ + hlen = lct_hdr_add_MODT_he(mclcb,(char*)lct_hdr, hlen, hdr_infos); + if (hlen < 0) goto bad; + } +#endif + if (hdr_infos->NONEWADU_present) { + ASSERT(hdr_infos->max_idf_adu >= mcl_iss); + hlen = lct_hdr_add_NONEWADU_he(mclcb,(char*)lct_hdr, hlen, hdr_infos); + if (hlen < 0) goto bad; + } + + lct_hdr->hdr_len = hlen >> 2; /* in 32-bit words */ + /* + * and finally swap the first 16 bits of header in network endian + */ + *(UINT16*)lct_hdr = htons(*(UINT16*)lct_hdr); + TRACELVL(5, (mcl_stdout, "<- lct_hdr_create: hlen=%d\n", hlen)) + return hlen; + +bad: + TRACELVL(5, (mcl_stdout, "<- lct_hdr_create: ERROR\n")) + return -1; +} + + +/** + * Add a FTI header extension, using the provided hdr_infos, depending + * on the FEC Encoding ID. + * + * With FEC Encoding IDs 0 (NO FEC) and 128 (SMALL BLOCK, LARGE BLOCK + * and EXPENDING): + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | HET = 64 | HEL | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Object Length (bytes) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | FEC Instance ID | Encoding Symbol Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Max Source Block Length (max_k) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * + * With FEC Encoding IDs and 129 (SMALL SYSTEMATIC): + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | HET = 64 | HEL | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Object Length (bytes) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | FEC Instance ID | Encoding Symbol Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |Max Source Block Length (max_k)| Max Nb of Enc. Symbols (max_n)| + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * + * With FEC Encoding ID 132 (for our LDGM/LDPC codec): + * see the draft-peltotalo-rmt-bb-fec-xor-pcm-rs-XX.txt I-D... + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | HET = 64 | HEL | | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + + * | Object Length (bytes) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | FEC Instance ID | Encoding Symbol Length | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Max Source Block Length (max_k) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Max Nb of Enc. Symbols (max_n) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * . seed (optional, 0 or 32 bit long) . + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Returns the new size of the header (bytes) with this + * header extension, or -1 if error. + */ + +static int +lct_hdr_add_FTI_he (mcl_cb *mclcb, + char *ptr, + int hlen, + hdr_infos_t *hdr_infos) +{ + UINT32 word1 = 0; + UINT32 word2 = 0; + UINT32 word3 = 0; + + TRACELVL(5, (mcl_stdout, "-> lct_hdr_add_FTI_he:\n")) + ASSERT(hdr_infos); + ASSERT(hdr_infos->FTI_present); + + switch (hdr_infos->fec_encoding_id) { + +#ifdef LDPC_FEC + case FEC_ENCODING_ID_PCM_FEC: + /* private format */ + word1 = (EXT_FTI << 24) | (6 << 16); + *(UINT32*)(ptr + hlen) = htonl(word1); + hlen += 4; + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->adu_len); + hlen += 4; + word2 = hdr_infos->fec_instance_id << 16 | + (hdr_infos->symbol_len); + *(UINT32*)(ptr + hlen) = htonl(word2); + hlen += 4; + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->max_k); + hlen += 4; + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->max_n); + hlen += 4; + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->fec_key); + hlen += 4; + break; +#endif /* LDPC_FEC */ + + case FEC_ENCODING_ID_SMALL_SYSTEMATIC_FEC: + word1 = (EXT_FTI << 24) | (4 << 16); + *(UINT32*)(ptr + hlen) = htonl(word1); + hlen += 4; + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->adu_len); + hlen += 4; + word2 = (hdr_infos->fec_instance_id << 16) | + (hdr_infos->symbol_len); + *(UINT32*)(ptr + hlen) = htonl(word2); + hlen += 4; + word3 = (hdr_infos->max_k) << 16 | (hdr_infos->max_n); + *(UINT32*)(ptr + hlen) = htonl(word3); + hlen += 4; + break; + + case FEC_ENCODING_ID_NO_FEC: + case FEC_ENCODING_ID_SMALL_LARGE_EXP_FEC: + word1 = (EXT_FTI << 24) | (4 << 16); + *(UINT32*)(ptr + hlen) = htonl(word1); + hlen += 4; + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->adu_len); + hlen += 4; + word2 = (hdr_infos->fec_instance_id << 16) | + (hdr_infos->symbol_len); + *(UINT32*)(ptr + hlen) = htonl(word2); + hlen += 4; + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->max_k); + hlen += 4; + break; + + default: + ASSERT(0); + } + + TRACELVL(5, (mcl_stdout, "<- lct_hdr_add_FTI_he: hlen=%d\n", hlen)) + return hlen; +} + + +/** + * Add a header extension, using either the provided hdr_infos, + * or by copying an externally supplied buffer containing the already + * formatted extension header. + * Updates the lct_hdr->hdr_len as required. + * + * This header extension is not LCT compliant (MCLv3 private extension) + * and will not be used e.g. in FLUTE sessions. + * + * Compact version: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |L|HET=NONEWADU | HEL = 1 | maximum TOI | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Long version: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * |L|HET=NONEWADU | HEL = 2 | 0 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | maximum TOI | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Returns the new size of the header (bytes) with this/these + * extension header(s), or -1 if error. + */ +static int +lct_hdr_add_NONEWADU_he (mcl_cb *mclcb, + char *ptr, + int hlen, + hdr_infos_t *hdr_infos) +{ + UINT32 word1 = 0; + + TRACELVL(5, (mcl_stdout, "-> lct_hdr_add_NONEWADU_he:\n")) + ASSERT(hdr_infos != NULL); + ASSERT(hdr_infos->NONEWADU_present); + ASSERT(hdr_infos->max_idf_adu >= mcl_iss); + if ((hdr_infos->max_idf_adu & 0xFFFF0000) == 0) { + /* + * use compact half word format since the maximum + * TOI does not exceed 16 bits + */ + word1 = (EXT_NONEWADU << 24) | (1 << 16) | (hdr_infos->max_idf_adu); + *(UINT32*)(ptr + hlen) = htonl(word1); + hlen += 4; + } else { + /* + * use long format since the maximum TOI exceeds 16 bits + */ + word1 = EXT_NONEWADU << 24 | (2 << 16); + *(UINT32*)(ptr + hlen) = htonl(word1); + hlen += 4; + *(UINT32*)(ptr + hlen) = htonl(hdr_infos->max_idf_adu); + hlen += 4; + } + TRACELVL(5, (mcl_stdout, "<- lct_hdr_add_NONEWADU_he: max=%d\n", + hdr_infos->max_idf_adu)) + return hlen; +} + + +/** + * Add FDT instance header EXT_FDT. + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | HET=192 | V | FDT instance ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Returns the new size of the header (bytes) with this/these + * extension header(s), or -1 if error. + */ +static int +lct_hdr_add_FDT_he (mcl_cb *mclcb, + char *ptr, + int hlen, + hdr_infos_t *hdr_infos) +{ + UINT32 word1 = 0; + + TRACELVL(5, (mcl_stdout, "-> lct_hdr_add_FDT_he:\n")) + ASSERT(hdr_infos != NULL); + ASSERT(mclcb->is_flute_compatible()); + ASSERT(hdr_infos->FDT_present); + + word1 = (EXT_FDT << 24) | (FDT_VERSION << 20) | + (hdr_infos->FDT_instanceid & 0x000FFFFF) ; + *(UINT32*)(ptr + hlen) = htonl(word1); + hlen += 4; + + TRACELVL(5, (mcl_stdout, "<- lct_hdr_add_FDT_he: FDT_instanceid=%d\n", + hdr_infos->FDT_instanceid)) + return hlen; +} + + +#ifdef METAOBJECT_USED +/** + * Add MODT instance header EXT_MODT. + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | HET=193 | V | MODT instance ID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * Returns the new size of the header (bytes) with this/these + * extension header(s), or -1 if error. + */ +static int +lct_hdr_add_MODT_he (mcl_cb *mclcb, + char *ptr, + int hlen, + hdr_infos_t *hdr_infos) +{ + UINT32 word1 = 0; + + TRACELVL(5, (mcl_stdout, "-> lct_hdr_add_MODT_he:\n")) + ASSERT(hdr_infos != NULL); + ASSERT(hdr_infos->MODT_present); + + word1 = (EXT_MODT << 24) | (MODT_VERSION << 20) | + (hdr_infos->FDT_instanceid & 0x000FFFFF); + *(UINT32*)(ptr + hlen) = htonl(word1); + hlen += 4; + + TRACELVL(5, (mcl_stdout, "<- lct_hdr_add_MODT_he: max=%d\n", + hdr_infos->max_idf_adu)) + return hlen; +} +#endif + + +/****** receiving side ********************************************************/ + + +/** + * Parses the LCT header of the received packet. + * Assumes that hdr_infos is already reset. + * Returns the size of the LCT header (bytes), -1 if error. + */ +int +lct_hdr_parse (mcl_cb *mclcb, + fixed_lct_hdr_t *lct_hdr, + hdr_infos_t *hdr_infos) +{ + INT32 hlen; /* length of fixed+variable LCT hdr (bytes) */ + UINT32 word1; + + TRACELVL(5, (mcl_stdout, "-> lct_hdr_parse:\n")) + /* + * first of all swap the first 16 bits of header in host endian + */ + *(UINT16*)lct_hdr = ntohs(*(UINT16*)lct_hdr); + /* sanity checks */ + if ((lct_hdr->version != LCT_VERSION) || (lct_hdr->reserved != 0)) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse: ERROR, unknown version|non 0 reserved field\n")) + goto bad_hdr; + } + /* check codepoint (in fact FEC Encoding ID) now */ + if ((lct_hdr->codepoint != FEC_ENCODING_ID_NO_FEC) + && (lct_hdr->codepoint != FEC_ENCODING_ID_SMALL_LARGE_EXP_FEC) + && (lct_hdr->codepoint != FEC_ENCODING_ID_SMALL_SYSTEMATIC_FEC) +#ifdef LDPC_FEC + && (lct_hdr->codepoint != FEC_ENCODING_ID_PCM_FEC) +#endif + ) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse: ERROR, unsupported codepoint/FEC encoding ID (%d)\n", + lct_hdr->codepoint)) + goto bad_hdr; + } + hdr_infos->fec_encoding_id = lct_hdr->codepoint; + /* check header length in 32 bit words */ + if (lct_hdr->hdr_len < (1 + (1 + lct_hdr->flag_c) + lct_hdr->flag_h + + lct_hdr->flag_s + lct_hdr->flag_o + + lct_hdr->flag_t + lct_hdr->flag_r)) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse: ERROR, hdr_len %d too short\n", + lct_hdr->hdr_len)) + goto bad_hdr; + } + /* + * header flags + */ + //hdr_infos->payload_id_present = lct_hdr->flag_p;/* FPI added by ALC */ + if (lct_hdr->flag_c != 0) { /* CC extension */ + PRINT_ERR((mcl_stderr, + "lct_hdr_parse: ERROR, CC of size > 32 bits not supported\n")) + goto bad_hdr; + } + if (lct_hdr->flag_t | lct_hdr->flag_r) { /* timing fields */ + PRINT_ERR((mcl_stderr, + "lct_hdr_parse: ERROR, SCT/ERT not supported\n")) + goto bad_hdr; + } + hdr_infos->close = (lct_hdr->flag_a == 1); /* CLOSE session flag */ + if (lct_hdr->flag_b) { /* CLOSE object flag */ + PRINT_ERR((mcl_stderr, + "lct_hdr_parse: ERROR, flag B (close object) not supported, ignored!\n")) + /*goto bad_hdr;*/ + } + hlen = sizeof(fixed_lct_hdr_t); + /* + * additional fields + */ + if (lct_hdr->flag_h) { + /* half-word TSI/TOI format */ + if ((lct_hdr->flag_s != 0) || (lct_hdr->flag_o != 0)) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse: ERROR, half-word format with more than 16 bit TSI or TOI not supported\n")) + goto bad_hdr; + } + /* 16 bit TSI (transport session idf) */ + word1 = ntohl(*(UINT32*)((char*)lct_hdr + hlen)); + hlen += 4; + hdr_infos->demux_label = (UINT32)(word1 >> 16); + /* 16 bit TOI (Transport Object Idf) */ + hdr_infos->TOI_present = true; + hdr_infos->idf_adu = (word1 & 0x0000FFFF); + } else { + if (lct_hdr->flag_s) { + /* 32 bit TSI (transport session Idf) */ + hdr_infos->demux_label = + ntohl(*(UINT32*)((char*)lct_hdr + hlen)); + hlen += 4; + } else { + hdr_infos->demux_label = 0; + } + if (lct_hdr->flag_o > 0) { + /* 32 bit TOI (Transport Object Idf) */ + hdr_infos->TOI_present = true; + if (lct_hdr->flag_o == 1) { + hdr_infos->idf_adu = + ntohl(*(UINT32*)((char*)lct_hdr + hlen)); + hlen += 4; + } else { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse: ERROR, TOI size > 32 bits not supported\n")) + goto bad_hdr; + } + } else { + hdr_infos->TOI_present = false; + hdr_infos->idf_adu = 0; + } + } + /* + * parse extension headers if any + */ + if (hlen < (int)(lct_hdr->hdr_len << 2)) { + hlen = lct_hdr_parse_he(mclcb,(char*)lct_hdr, hlen, hdr_infos); + if (hlen < 0) goto bad_hdr; + } + if (hlen != (int)(lct_hdr->hdr_len << 2)) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse: ERROR, bad hdr_len (announced %d, actual %d)\n", + lct_hdr->hdr_len, (hlen>>2) - 2)) + goto bad_hdr; + } + TRACELVL(5, (mcl_stdout, "<- lct_hdr_parse: demux_label=%d\n", + hdr_infos->demux_label)) + + return hlen; + +bad_hdr: + PRINT_ERR((mcl_stderr, "lct_hdr_parse: ERROR, bad header, dropped\n")) + TRACELVL(5, (mcl_stdout, "<- lct_hdr_parse: ERROR\n")) + return -1; +} + + +/** + * Parses the header extensions of the received packet. + * Returns the new size of the header (bytes) with the HE field(s), + * or <0 if error. + */ +static int +lct_hdr_parse_he (mcl_cb *mclcb, + char *ptr, + int hlen, + hdr_infos_t *hdr_infos) +{ + fixed_lct_hdr_t *lct_hdr = (fixed_lct_hdr_t*)ptr; + UINT32 word1; /* first word of the HE */ + UINT32 word2; + UINT32 word3; + + int can_ignore = 0; /* can be safely ignored bit */ + int HET; + int HEL; + int eh_len; /* hdr extension length (32bit words) */ + + TRACELVL(5, (mcl_stdout, "-> lct_hdr_parse_he:\n")) + /* + * go through all HE + */ + for (eh_len = lct_hdr->hdr_len - (hlen >> 2); eh_len > 0; ) { + /* at least one word long! */ + word1 = ntohl(*(UINT32*)(ptr + hlen)); + hlen += 4; + eh_len--; + /*can_ignore = word1 >> 31;*/ + can_ignore = 0; /* false for the present */ + HET = (word1 & 0xFF000000) >> 24; + HEL = (word1 & 0x00FF0000) >> 16; /* invalid if HET<64 */ + TRACELVL(5, (mcl_stdout, + " lct_hdr_parse_he: new HE, word=x%x, HET=%d, HEL=%d\n", + word1, HET, HEL)) + switch (HET) { + case EXT_FDT: + if (mclcb->is_flute_compatible() == false) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_he: ERROR, EXT_FDT not supported if not in FLUTE compatibility mode\n")) + goto bad; + } + if ((word1 & 0x00F00000) >> 20 != FDT_VERSION) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_he: ERROR, bad FDT version (expected %d, got %d)\n", + FDT_VERSION, (word1 & 0x00F00000) >> 20)) + goto bad; + } + hdr_infos->FDT_instanceid= word1 & 0x000FFFFF; + hdr_infos->FDT_present = true; + break; + +#ifdef METAOBJECT_USED + case EXT_MODT: + if ((word1 & 0x00F00000) >> 20 != MODT_VERSION) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_he: ERROR, bad MODT version (expected %d, got %d)\n", + FDT_VERSION, (word1 & 0x00F00000) >> 20)) + goto bad; + } + hdr_infos->FDT_instanceid= word1 & 0x000FFFFF; + hdr_infos->MODT_present = true; + break; +#endif + + case EXT_FTI: + /* + * the FTI format depends on the FEC Encoding ID, + * which has been checked before... + */ + /* assume the length (HEL) is ok, it will be checked + * just bellow... */ + if ((word1 & 0X0000FFFF) != 0) { + /* we don't support object length encoded with + * more than 32 bits */ + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_he: ERROR, upper 16 bits of 48 bit object length field non zero (not supported)\n")); + goto bad; + } + hdr_infos->adu_len = ntohl(*(UINT32*)(ptr + hlen)); + hlen += 4; + eh_len--; + word2 = ntohl(*(UINT32*)(ptr + hlen)); + hdr_infos->fec_instance_id=(word2 & 0xFFFF0000)>> 16; + + switch (hdr_infos->fec_encoding_id) { +#ifdef LDPC_FEC + case FEC_ENCODING_ID_PCM_FEC: + if (HEL != 5 && HEL != 6) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_he: ERROR, bad HEL (expected 5 or 6, got %d) for FTI of Encoding ID %d\n", + HEL, hdr_infos->fec_encoding_id)) + goto bad; + } + hdr_infos->symbol_len = word2 & 0x0000FFFF; + hlen += 4; + eh_len--; + hdr_infos->max_k = ntohl(*(UINT32*)(ptr + hlen)); + hlen += 4; + eh_len--; + hdr_infos->max_n = ntohl(*(UINT32*)(ptr + hlen)); + hlen += 4; + eh_len--; + if (HEL == 5) { + hdr_infos->fec_key = 0; + } else { + hdr_infos->fec_key = ntohl(*(UINT32*)(ptr + hlen)); + hlen += 4; + eh_len--; + } + break; +#endif /* LDPC_FEC */ + + case FEC_ENCODING_ID_SMALL_SYSTEMATIC_FEC: + if (HEL != 4) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_he: ERROR, bad HEL (%d) for FTI of Encoding ID %d\n", + HEL, hdr_infos->fec_encoding_id)) + goto bad; + } + hdr_infos->symbol_len=word2 & 0x0000FFFF; + hlen += 4; + eh_len--; + word3 = ntohl(*(UINT32*)(ptr + hlen)); + hdr_infos->max_k = word3 >> 16; + hdr_infos->max_n = word3 & 0x0000FFFF; + hlen += 4; + eh_len--; + break; + + case FEC_ENCODING_ID_NO_FEC: + case FEC_ENCODING_ID_SMALL_LARGE_EXP_FEC: + if (HEL != 4) { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_he: ERROR, bad HEL (%d) for FTI of Encoding ID %d\n", + HEL, hdr_infos->fec_encoding_id)) + goto bad; + } + hdr_infos->symbol_len=word2 & 0x0000FFFF; + hlen += 4; + eh_len--; + hdr_infos->max_k = ntohl(*(UINT32*)(ptr + hlen)); + hlen += 4; + eh_len--; + break; + + default: + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_he: ERROR, unsupported FEC enconding ID (%d) in FTI hdr ext\n", hdr_infos->fec_encoding_id)) + goto bad; + } + hdr_infos->FTI_present = true; + break; + + case EXT_NONEWADU: + if (HEL == 1) { + hdr_infos->max_idf_adu = + (UINT32)(word1 & 0x0000FFFF); + } else if (HEL == 2) { + hdr_infos->max_idf_adu = + ntohl(*(UINT32*)(ptr + hlen)); + hlen += 4; + } else { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_he: ERROR, bad NONEWADU hdr ext\n")) + goto bad; + } + eh_len--; + hdr_infos->NONEWADU_present = true; + break; + + case EXT_NOP: + /* ignore */ + break; + + default: + if (can_ignore) { + /* first word already counted */ + hlen += (HET < 128) ? (HEL << 2) - 4 : 0; + eh_len -= (HET < 64) ? HEL - 1 : 0; + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_HE: WARNING, unsupported HET %d (HEL=%d, word=x%x), ignored!\n", + HET, HEL, word1)) + break; + } else { + PRINT_ERR((mcl_stderr, + "lct_hdr_parse_HE: ERROR, unsupported HET %d (HEL=%d, word=x%x)\n", + HET, HEL, word1)) + return -1; + } + } + } + TRACELVL(5, (mcl_stdout, "<- lct_hdr_parse_he:\n")) + return hlen; + +bad: + TRACELVL(5, (mcl_stdout, "<- lct_hdr_parse_he: ERROR\n")) + return -1; +} + diff --git a/src/alc/mcl_lct_hdr.h b/src/alc/mcl_lct_hdr.h new file mode 100644 index 0000000..b8e64ec --- /dev/null +++ b/src/alc/mcl_lct_hdr.h @@ -0,0 +1,181 @@ +/* $Id: mcl_lct_hdr.h,v 1.17 2005/01/11 13:12:29 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_LCT_HDR_H /* { */ +#define MCL_LCT_HDR_H + + +#define LCT_VERSION 1 + +#define CC_ID_RLC 1 + + +/* + * structure used for communications between the various header + * creation/analysis functions and the rest of the code + */ +typedef struct hdr_infos { + /* common fields */ + UINT32 demux_label; /* demux label, also known as TSI */ + UINT32 fec_encoding_id;/* FEC encoding ID (RFC3452) */ + /* fields used for TOI */ + bool TOI_present; /* tx or rx: TOI present */ + UINT32 idf_adu; /* ADU identifier (AKA TOI) */ + /* fields used by FPI */ + bool FPI_present; /* tx or rx: FEC payload ID present */ + UINT32 idf_block; /* BLOCK identifier */ + UINT32 idf_du; /* DU identifier */ + bool is_fec; /* true if DU has FEC content */ + /* fields used for File Delivery Table (FDT) with FLUTE */ + bool FDT_present; /* tx or rx: FDT present */ +#ifdef METAOBJECT_USED + bool MODT_present; /* tx or rx: MODT present */ +#endif + UINT32 FDT_instanceid; /* also used as MODT instanceid */ + /* fields used by FEC object Tx Info (FTI) */ + bool FTI_present; /* tx or rx: FTI present */ + UINT32 adu_len; /* ADU length in bytes */ + UINT32 k; /* _current_ src blk len in nb symbols*/ + /* used by some FPI */ + UINT32 max_k; /* max src blk len in nb of symbols */ + /* used by some FTI */ + UINT32 max_n; /* max enc blk len in nb of symbols */ + /* used by some FTI */ + UINT16 symbol_len; /* full-sized symbol length in bytes */ + UINT16 fec_instance_id;/* FEC instance ID (RFC3452) */ +#ifdef LDPC_FEC + UINT32 fec_key; /* LDGM/LDPC specific: random seed */ +#endif + /* fields used by NONEWADU */ + bool NONEWADU_present;/* tx or rx: NONEWADU present */ + UINT32 max_idf_adu; /* highest ADU identifier in session */ + /* fields used by CLOSE */ + bool close; /* CLOSE sig: boolean */ +} hdr_infos_t; + + +/* + * LCT header format + */ +typedef struct fixed_lct_hdr { +#ifdef _BIT_FIELDS_LTOH + UINT16 flag_b:1, + flag_a:1, + flag_r:1, + flag_t:1, + flag_h:1, + flag_o:2, + flag_s:1, + reserved:2, + flag_c:2, + version:4; + + u_char hdr_len; + + u_char codepoint; +#else /* the sames, in "natural" writting order... */ + UINT16 version:4, /* LCT version Number */ + flag_c:2, /* congestion control flag */ + reserved:2, /* unused; must be zero */ + flag_s:1, /* transport session identifier flag */ + flag_o:2, /* transport object identifier flag */ + flag_h:1, /* half word flag */ + flag_t:1, /* Sender Current Time (SCT) present */ + flag_r:1, /* Expected Residual Time ERT present */ + flag_a:1, /* close object flag */ + flag_b:1; /* close session flag */ + + u_char hdr_len; /* length of variable portion of LCT */ + /* header in units of 32-bit words */ + /* (starting from 3rd 32-bit word) */ + + u_char codepoint; /* opaque idf used by payload decoder */ +#endif + UINT32 cci; /* opaque congestion control header */ +} fixed_lct_hdr_t; + + +/* types of signaling */ +#define EH_SIG 2 /* ALC/LCT signaling */ +/* ... others... */ + + +/* + * Extension Headers (EH) types + */ +/* official EH defined by LCT */ +#define EXT_NOP 0 +#define EXT_AUTH 1 +/* official ALC-specific EH */ +#define EXT_FTI 64 /* FEC Object Transmission Information */ +/* private EH (not in LCT/ALC drafts) */ +#define EXT_NONEWADU 65 /* no new ADU will be submitted by the */ + /* application. Not used by FLUTE. */ +/* FLUTE specific */ +#define EXT_FDT 192 /* File Delivery Table Instance Header */ + +#define FDT_VERSION 1 /* FDT version defined in FLUTE spec */ + +#ifdef METAOBJECT_USED +/* private EH */ +#define EXT_MODT 193 /* Meta-Object Description Table Instance hdr */ + +#define MODT_VERSION 1 /* private version number */ +#endif + +/* + * Additional signaling types: must be coherent with the EXT_XXX types + * Those are not EH... + */ +#define SIG_CLOSE 254 /* end of tx */ + + +/* + * Public function prototypes. + */ + +/** + * Create an LCT header. + * @param mclcb + * @param lct_hdr pointer to the begining of the LCT header. + * @param hdr_infos pointer to the header info structure, that explains + * how to create the LCT header. + * @return + */ +extern int lct_hdr_create (class mcl_cb *mclcb, fixed_lct_hdr_t *lct_hdr, + hdr_infos_t *hdr_infos); + +/** + * Parse an LCT header. + * @param mclcb + * @param lct_hdr pointer to the begining of the LCT header to analyze. + * @param hdr_infos pointer to the header info structure where is + * stored the information contained in the LCT header. + * @return + */ +extern int lct_hdr_parse (class mcl_cb *mclcb, fixed_lct_hdr_t *lct_hdr, + hdr_infos_t *hdr_infos); + + + + + +#endif /* } MCL_LCT_HDR_H */ diff --git a/src/alc/mcl_lib.cpp b/src/alc/mcl_lib.cpp new file mode 100644 index 0000000..eb96c69 --- /dev/null +++ b/src/alc/mcl_lib.cpp @@ -0,0 +1,2771 @@ +/* $Id: mcl_lib.cpp,v 1.72 2005/05/23 14:55:51 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * This file contains the entry functions of the MCL library. + */ + +#include "mcl_includes.h" + + +/****** external functions of the library *************************************/ + +/** + * Open an MCL_ALC session. + * => See header file for more informations. + */ +int +mcl_open (const char* mode) +{ + mcl_cb *mclcb; + mcl_tx_rx_mode mcl_mode; + + // check mode and translate to internal mcl mode + if (!strcmp("w", mode)) { + mcl_mode = MCL_IS_A_SENDER_ONLY; + } else if (!strcmp("r", mode)) { + mcl_mode = MCL_IS_A_RECEIVER_ONLY; + } else { + PRINT_ERR((mcl_stderr, "mcl_open: ERROR unknown mode %s\n", mode)) + goto bad; + } + mclcb = new mcl_cb(mcl_mode); // to do immediately before anything else + if (!mclcb) { + PRINT_ERR((mcl_stderr, "mcl_open: ERROR, mclcb constructor failed\n")) + goto bad; + } + TRACELVL(5, (mcl_stdout, "<- mcl_open: \"%s\" return %d\n", + mode, (int)mclcb->get_id())) + return (int)(mclcb->get_id()); + +bad: + PRINT_ERR((mcl_stderr, "mcl_open: ERROR\n")) + return -1; +} + + +/** + * Close an MCL_ALC session. + * => See header file for more informations. + */ +int +mcl_close (int id) +{ + int max_adu; /* highest ADU seq number */ + mcl_cb *mclcb; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_close: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + TRACELVL(5, (mcl_stdout, "-> mcl_close: id=%d\n", id)) + + if (mclcb->is_a_sender() && mclcb->fsm.can_send_data(mclcb)) { + /* data has already been submitted => send NO_NEW_ADU first + * unless we are in FLUTE mode */ + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_CALLED); + max_adu = mclcb->tx.get_highest_toi(mclcb); + if (mclcb->is_flute_compatible() == false) { + SendNONEWADU(mclcb, max_adu); + } + /* wait till everything has been sent... */ + while (!mclcb->fsm.close_can_return(mclcb)) { + TRACELVL(5, (mcl_stdout, " mcl_close: (sender) wait a bit...\n")) + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + }; + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_RETURN); + } else if (mclcb->is_a_sender()) { + /* data has never been submitted => send a CLOSE and return */ + /* yes, we really need to finish initialization! */ +#ifdef SVSOA_RECV + mclcb->finish_session_init_if_needed(1); +#else + mclcb->finish_session_init_if_needed(); +#endif + + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_CALLED); + SendCLOSE(mclcb); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_SENT); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_RETURN); + } else { + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_CALLED); + while (!mclcb->fsm.close_can_return(mclcb)) { + TRACELVL(5, (mcl_stdout, " mcl_close: (receiver) wait a bit...\n")) + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + }; + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_RETURN); + } + + /* + * destroy the rx thread now... + */ +#ifdef WIN32 + if (mclcb->rx_thread) mclcb->test_cancel = TRUE; + mclcb->unlock(); /* tx and rx threads might be blocked */ + if (mclcb->rx_thread) { + DWORD res = WaitForSingleObject((HANDLE)mclcb->rx_thread, 5000); + if (res == WAIT_FAILED) { + if (GetLastError()==ERROR_INVALID_HANDLE) { + Sleep(100); + } else if (GetLastError()== ERROR_ACCESS_DENIED) { + /* by Florian Geyer */ + Sleep(1); + } else { + PRINT_ERR((mcl_stderr, + "mcl_close: ERROR, WaitForSingleObject() failed (%d)\n", + GetLastError())) + mcl_exit(-1); + } + } + } +#else // UNIX + if (mclcb->rx_thread) pthread_cancel(mclcb->rx_thread); + mclcb->unlock(); /* tx and rx threads might be blocked */ + if (mclcb->rx_thread) pthread_join(mclcb->rx_thread,NULL); +#endif // OS + mclcb->rx_thread = 0; + /* free everything */ + mclcb->free_everything(); + TRACELVL(5, (mcl_stdout, "<- mcl_close:\n")) + delete mclcb; + return (close(id)); +} + + +/** + * Close the session immediately and send CLOSE messages if we + * are a source. + * => See header file for more informations. + */ +int +mcl_abort (int id) +{ + mcl_cb *mclcb; + int err; /* return code from close */ + int trylock_err; /* return code from trylock: 0 if ok, or EBUSY*/ + static bool in_abort = false;/* return if true (someone else in abort)*/ + + if (in_abort) { + //TRACE((mcl_stdout, "<- mcl_abort: someone else in abort\n")) + return 0; /* don't try to call close in abort mode */ + } + in_abort = true; /* take "lock" */ + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_abort: ERROR, bad id %d\n", id)) + in_abort = 0; /* release "lock" */ + return 0; /* don't try to call close in abort mode */ + } + /* + * do not call lock in an async signal environment... + * this is a problem as mcl_abort is usually called after a CTRL-C + * so, use trylock instead and take lock only if available. + */ + trylock_err = mclcb->trylock(); + TRACELVL(5, (mcl_stdout, "-> mcl_abort: id=%d\n", id)) + if (mclcb->is_a_sender()) { + /* send a CLOSE and return, no matter what is current state */ + /* yes, we really need to finish initialization! */ +#ifdef SVSOA_RECV + mclcb->finish_session_init_if_needed(1); +#else + mclcb->finish_session_init_if_needed(); +#endif + mclcb->fsm.update_tx_state(mclcb, TEVENT_ABORT); + SendCLOSE(mclcb); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_SENT); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_RETURN); + } else { + if (mclcb->fsm.is_opened(mclcb)) { + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_CALLED); + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_RETURN); + } + /* else already in RSTATE_NIL, do nothing */ + } + /* + * de-register the session (e.g. used by the periodic timer thread) + */ + mclcb_tab[id] = NULL; + /* + * destroy the rx thread now... + */ +#ifdef WIN32 + if (mclcb->rx_thread) mclcb->test_cancel = TRUE; + if (trylock_err == 0) + mclcb->unlock(); /* tx and rx threads might be blocked */ + if (mclcb->rx_thread) { + DWORD res = WaitForSingleObject((HANDLE)mclcb->rx_thread, 5000); + if (res == WAIT_FAILED) { + if (GetLastError()==ERROR_INVALID_HANDLE) { + Sleep(100); + } else { + PRINT_ERR((mcl_stderr, "mcl_abort ERROR: WaitForSingleObject() failed (%d)\n", GetLastError())) + mcl_exit(-1); + } + } + } +#else // UNIX + if (mclcb->rx_thread) pthread_cancel(mclcb->rx_thread); + if (trylock_err == 0) + mclcb->unlock(); /* tx and rx threads might be blocked */ + if (mclcb->rx_thread) pthread_join(mclcb->rx_thread, NULL); +#endif // OS + + mclcb->rx_thread = 0; + /* free everything */ + mclcb->free_everything(); + TRACELVL(5, (mcl_stdout, "<- mcl_abort:\n")) + delete mclcb; + err = close(id); + in_abort = false; /* release "lock" */ + return err; +} + + +/** + * Get or set control parameters for the session. + * WARNING: usually the tx and rx contexts are still not created! + * This is only done during the first call to mcl_send or mcl_recv... + * => See header file for more informations. + */ +int +mcl_ctl (int id, + int optname, + void *optvalue, + int optlen) +{ + mcl_cb *mclcb; + int err; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_ctl: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + if (mclcb->fsm.is_opened(mclcb) == false) { + /* not yet opened */ + PRINT_ERR((mcl_stderr, "mcl_ctl: ERROR, not opened\n")) + mclcb->unlock(); + return -1; + } + TRACELVL(5, (mcl_stdout, "-> mcl_ctl: id=%d\n", id)) + // call the internal ctl function where work will be done + err = mcl_ctl2(mclcb, optname, optvalue, optlen); + TRACELVL(5, (mcl_stdout, "<- mcl_ctl: return %d\n", err)) + mclcb->unlock(); + return err; +} + + +/** + * Private version of the MCL control function. + */ +int +mcl_ctl2 (mcl_cb *const mclcb, + int optname, + void *optvalue, + int optlen) +{ + char opt_found; + + TRACELVL(5, (mcl_stdout, "-> mcl_ctl2: optname=%d, optvalue=x%x, optlen=%d\n", + optname, (int)optvalue, optlen)) + /* + * called first (before mcl_open) to set the mcl options + * or call the internal application + */ + switch (optname) { + + case MCL_OPT_LAYER_NB: /* set the number of tx layers */ + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_LAYER_NB ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + mclcb->max_nb_layers = *(int*)optvalue; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_LAYER_NB (%d)\n", mclcb->max_nb_layers)) + if (mclcb->max_nb_layers < 1 || mclcb->max_nb_layers > MAX_NB_TX_LAYERS) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_LAYER_NB ERROR: layer %d out of range ([1; %d])\n", + mclcb->max_nb_layers, MAX_NB_TX_LAYERS)) + mclcb->max_nb_layers = 1; + goto error; + } + break; + + case MCL_OPT_TX_PROFILE: /* select a pre-defined tx profile */ + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TX_PROFILE ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_TX_PROFILE (%d)\n", *(int*)optvalue)) + if (mcl_set_tx_profile(mclcb, *(int*)optvalue) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TX_PROFILE: mcl_set_tx_profile() failed\n")) + goto error; + } + break; + + case MCL_OPT_PRINT_TX_PROFILE: /* print the current tx profile */ + if (optvalue || optlen != 0) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_PRINT_TX_PROFILE ERROR: non null optvalue or optlen > 0\n")) + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_PRINT_TX_PROFILE\n")) + if (mcl_print_tx_profile(mclcb) != MCL_OK) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_PRINT_TX_PROFILE: mcl_print_tx_profile() failed\n")) + goto error; + } + break; + + case MCL_OPT_DATAGRAM_SIZE: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_DATAGRAM_SIZE ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if (mclcb->set_max_datagram_size(*(int*)optvalue) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_DATAGRAM_SIZE ERROR: size %d out of range\n", + *(int*)optvalue)) + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_DATAGRAM_SIZE (%d)\n", mclcb->get_max_datagram_size())) + break; + + case MCL_OPT_TX_RATE: { + double rate; + if (!optvalue || optlen != sizeof(double)) { + PRINT_ERR((mcl_stderr, "mcl_ctl: MCL_OPT_TX_RATE ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(double))) + goto error; + } + rate = *(double*)optvalue; /* in packets/s on base layer */ +#if 0 +#define MCL_MAX_TX_RATE 4000.0 + if (rate <= 0.0 || rate > MCL_MAX_TX_RATE) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TX_RATE ERROR: rate %f out of range ([1; %f] pkts/s)\n", + rate, MCL_MAX_TX_RATE)) + goto error; + } +#else + /* no upper bound */ + if (rate <= 0.0) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TX_RATE ERROR: rate %f out of range (must be > 0.0)\n", + rate)) + goto error; + } +#endif + mclcb->rate_on_base_layer = rate; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_TX_RATE (%f)\n", rate)) + break; + } + + case MCL_OPT_SET_NETIF_NAME: + if (!optvalue || optlen <= 0 || optlen > MAX_NAME_LEN) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NETIF_NAME ERROR: null optvalue or out of range optlen (got %d, expected ]0; %d])\n", + optlen, MAX_NAME_LEN)) + goto error; + } + if (optlen != (int)strlen((char*)optvalue)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NETIF_NAME ERROR: optlen (%d) different from string optvalue len (%d)\n", + optlen, MAX_NAME_LEN)) + goto error; + } + if ((mclcb->mcast_if_name = (char*)calloc(1, optlen + 1)) == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NETIF_NAME ERROR: calloc failed.\n")) + goto error; + } + strncpy(mclcb->mcast_if_name, (char*)optvalue, optlen); + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_SET_NETIF_NAME (%s)\n", mclcb->mcast_if_name)) + break; + + case MCL_OPT_SET_NETIF_ADDR: + /* specify sockaddr of the network interface to use */ + if (!optvalue) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NETIF_ADDR ERROR: null optvalue\n")) + goto error; + } + switch (optlen) { + case (sizeof(struct sockaddr_in)): { + struct sockaddr_in sin; + + sin = *(struct sockaddr_in*)optvalue; + /* assumes addr/port in network order */ + mclcb->mcast_if_addr = new mcl_addr(); + mclcb->mcast_if_addr->set_addr_struct(&sin); + break; + } +#ifdef INET6 + case (sizeof(struct sockaddr_in6)): { + struct sockaddr_in6 sin6; + + sin6 = *(struct sockaddr_in6*)optvalue; + /* assumes addr/port in network order */ + mclcb->mcast_if_addr = new mcl_addr(); + mclcb->mcast_if_addr->set_addr_struct(&sin6); + break; + } +#endif // INET6 + default: + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NETIF_ADDR ERROR: bad optlen (got %d, expected %d or %d)\n", + optlen, sizeof(struct sockaddr_in), + sizeof(struct sockaddr_in6))) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_NETIF_ADDR (%s)\n", + mclcb->mcast_if_addr->get_addr_string())) + break; + + case MCL_OPT_PORT: { + int port; + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_PORT ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + /* port in host byte order */ + //mclcb->myport = *(int*)optvalue; + port = *(int*)optvalue; + mclcb->addr.set_port((u_short)port); + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_PORT (%d)\n", port)) + break; + } + + case MCL_OPT_ADDR: + if (!optvalue || optlen != sizeof(UINT32)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_ADDR ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(UINT32))) + goto error; + } + /* addr in host byte order */ + mclcb->addr.set_addr(*(UINT32*)optvalue); + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_ADDR (%s addr %s)\n", + (mclcb->addr.is_multicast_addr() ? "multicast" : "unicast"), + mclcb->addr.get_addr_string())) + break; + + case MCL_OPT_SET_SSM: { + /* set the SSM (Source Specific Multicast) */ + bool val; + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_SSM ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } +#ifdef SSM + if (*(int*)optvalue == 0) { + val = false; + } else if (*(int*)optvalue == 1) { + val = true; + } else { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_SSM ERROR: arg %d out of range (0/1)\n", + *(int*)optvalue)) + goto error; + } + mclcb->rx.ssm = val; + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_SSM (%d)\n", val)) + break; +#else /* SSM */ + if (*(int*)optvalue != 0) { + PRINT_ERR((mcl_stderr, "mcl_ctl: MCL_OPT_SET_SSM ERROR: SSM (Source Specific Multicast) not supported. Recompile with the SSM define set.\n")) + goto error; + } +#endif /* SSM */ + } + + case MCL_OPT_SRC_ADDR: + /* specify sockaddr to use as source address */ + if (!optvalue) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SRC_ADDR ERROR: null optvalue\n")) + goto error; + } + switch (optlen) { + case (sizeof(struct sockaddr_in)): { + struct sockaddr_in sin; + + sin = *(struct sockaddr_in*)optvalue; + /* assumes addr/port in network order */ + mclcb->rx.src_addr.set_addr_struct(&sin); + mclcb->rx.check_src_addr = true; + break; + } +#ifdef INET6 + case (sizeof(struct sockaddr_in6)): { + struct sockaddr_in6 sin6; + + sin6 = *(struct sockaddr_in6*)optvalue; + /* assumes addr/port in network order */ + mclcb->rx.src_addr.set_addr_struct(&sin6); + mclcb->rx.check_src_addr = true; + break; + } +#endif // INET6 + default: + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SRC_ADDR ERROR: bad optlen (got %d, expected %d or %d)\n", + optlen, sizeof(struct sockaddr_in), + sizeof(struct sockaddr_in6))) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SRC_ADDR (%s %s addr %s)\n", + (mclcb->rx.src_addr.is_ipv4_addr() ? "IPv4" : "IPv6"), + (mclcb->rx.src_addr.is_multicast_addr() ? "multicast" + : "unicast"), + mclcb->rx.src_addr.get_addr_string())) + break; + + case MCL_OPT_BIND: + /* specify sockaddr to use like a bind syscall */ + if (!optvalue) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_BIND ERROR: null optvalue\n")) + goto error; + } + switch (optlen) { + case (sizeof(struct sockaddr_in)): { + struct sockaddr_in sin; + + sin = *(struct sockaddr_in*)optvalue; + /* assumes addr/port in network order */ + mclcb->addr.set_addr_struct(&sin); + break; + } +#ifdef INET6 + case (sizeof(struct sockaddr_in6)): { + struct sockaddr_in6 sin6; + + sin6 = *(struct sockaddr_in6*)optvalue; + /* assumes addr/port in network order */ + mclcb->addr.set_addr_struct(&sin6); + break; + } +#endif // INET6 + default: + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_BIND ERROR: bad optlen (got %d, expected %d or %d)\n", + optlen, sizeof(struct sockaddr_in), + sizeof(struct sockaddr_in6))) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_BIND (%s %s addr %s)\n", + (mclcb->addr.is_ipv4_addr() ? "IPv4" : "IPv6"), + (mclcb->addr.is_multicast_addr() ? "multicast" + : "unicast"), + mclcb->addr.get_addr_string())) + break; + + case MCL_OPT_TTL: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TTL ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + mclcb->ttl = (UINT16)(*(int*)optvalue); + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_TTL (%d)\n", mclcb->ttl)) + if (mclcb->ttl > 255) { + /* ttl 0 means do not leave host which is valid */ + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TTL ERROR: TTL %d out of range ([0; %d])\nNB: TTL == 0 means do not leave host\n", + mclcb->ttl, 127)) + mclcb->ttl = 1; + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: ttl=%d\n", mclcb->ttl)) + break; + + case MCL_OPT_DEMUX_LABEL: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_DEMUX_LABEL ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + mclcb->demux_label = (*(int*)optvalue); + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_DEMUX_LABEL (%d)\n", + mclcb->demux_label)) + break; + + case MCL_OPT_VERBOSITY: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_VERBOSITY ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + if (mclcb->set_verbosity(*(int*)optvalue) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_VERBOSITY ERROR: verbose arg %d out of range\n", *(int*)optvalue)) + mclcb->set_verbosity(0); // set a conservative value + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_VERBOSITY (%d)\n", mclcb->get_verbosity())) + break; + + case MCL_OPT_STATS: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_STATS ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if (mclcb->set_stats_level(*(int*)optvalue) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_STATS ERROR: statistics arg %d out of range\n", *(int*)optvalue)) + mclcb->set_stats_level(0); // set a conservative value + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_STATS (%d)\n", mclcb->get_stats_level())) + break; + +#if 0 + case MCL_OPT_DEBUG: /* debug mode : no tx or rx thread */ + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_DEBUG\n")) + mclcb->debug = 1; + break; +#endif + + case MCL_OPT_MOREABOUT: + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_MOREABOUT\n")) + mcl_moreabout(); + break; + + case MCL_OPT_TMP_DIR: /* name of directory to use for temp files */ + if (!optvalue || optlen <= 0 || optlen >= MAX_FILE_NAME_LEN) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TMP_DIR ERROR: null optvalue or bad optlen (got %d, expected in ]0; %d[)\n", + optlen, MAX_FILE_NAME_LEN)) + goto error; + } + strncpy(mcl_tmp_dir_name, (char*)optvalue, optlen); + mcl_tmp_dir_name[MAX_FILE_NAME_LEN-1] = '\0'; /* security */ + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_TMP_DIR %s\n", mcl_tmp_dir_name)) + break; + + case MCL_OPT_SET_FLUTE_MODE: + if (optvalue || optlen != 0) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FLUTE_MODE ERROR: no argument needed)\n")) + goto error; + } + mclcb->set_flute_mode(true); + TRACELVL(5, (mcl_stdout," mcl_ctl: MCL_OPT_SET_FLUTE_MODE\n")) + break; + + case MCL_OPT_SET_NEXT_TOI: { + UINT32 toi; + if (!optvalue || optlen != sizeof(UINT32)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NEXT_TOI ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(UINT32))) + goto error; + } + toi = (*(UINT32*)optvalue); + if (mclcb->tx.set_next_toi(toi) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NEXT_TOI ERROR: mcl_tx::set_next_toi() failed\n")) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_NEXT_TOI (%d)\n", toi)) + break; + } + + case MCL_OPT_SET_NEXT_ADU_HIGH_IMPORTANCE: + /* set the next ADU of beeing of HIGH importance */ + /* (e.g. for control data) */ + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_NEXT_ADU_HIGH_IMPORTANCE\n")) + mclcb->tx.next_adu_is_of_high_prio = true; + break; + + case MCL_OPT_FLUSH_HIGH_IMPORTANCE_OBJECTS: { + /* flush all high priority data */ + INT32 lay; + txlay_t *tl; + + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_FLUSH_HIGH_IMPORTANCE_OBJECTS\n")) + for (lay = 0, tl = mclcb->txlay_tab; lay < mclcb->max_nb_layers; lay++, tl++) + { + tl->tx_high_flush = true; + } + break; + } + +#ifdef METAOBJECT_USED + case MCL_OPT_SET_META_OBJECT_ONLY_MODE: + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_META_OBJECT_ONLY_MODE\n")) + mclcb->meta_obj_layer->metaobject_only_mode = true; + break; + + case MCL_OPT_KEEP_META_OBJECT: + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_KEEP_META_OBJECT\n")) + if (!mclcb->is_a_sender() || + (mclcb->meta_obj_layer->completed == false && mclcb->meta_obj_layer->in_use() == true)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_KEEP_META_OBJECT ERROR: not a sender or KEEP_META_OBJECT mode already set\n")) + goto error; + } + mclcb->meta_obj_layer->create_meta_object(); + break; + + case MCL_OPT_PUSH_META_OBJECT: + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_PUSH_META_OBJECT\n")) + if (!mclcb->is_a_sender() || + !(mclcb->meta_obj_layer->completed == false && mclcb->meta_obj_layer->in_use() == true)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_PUSH_META_OBJECT ERROR: not a sender or KEEP_META_OBJECT mode is not set\n")) + goto error; + } + //mclcb->meta_obj_layer->close_meta_object(mclcb->next_adu_seq); + mclcb->meta_obj_layer->close_meta_object(mclcb->tx.get_next_toi()); + // mclcb->tx.incr_next_toi() // XXX: VR: is it needed ??? + break; +#endif /* METAOBJECT_USED */ + + case MCL_OPT_KEEP_DATA: /* step1: wait before doing ADU scheduling */ + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_KEEP_DATA\n")) + if (mclcb->tx.keep_data(mclcb) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_KEEP_DATA ERROR: mcl_tx::keep_data() failed\n")) + goto error; + } + break; + + case MCL_OPT_PUSH_DATA: /* step2: now perform ADU scheduling and send */ + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_PUSH_DATA\n")) + if (mclcb->tx.push_data(mclcb) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_PUSH_DATA ERROR: mcl_tx::push_data() failed\n")) + goto error; + } + break; + + case MCL_OPT_STOP_TRANSMITTING_ADU: { + TRACELVL(5, (mcl_stdout, + "-> mcl_ctl: MCL_OPT_STOP_TRANSMITTING_ADU\n")) + + UINT64 toi; + INT32 lay; + txlay_t *tl; + adu_t *adu = NULL; + + if (mclcb->is_a_sender() == false) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_STOP_TRANSMITTING_ADU ERROR: only possible in SENDER mode\n")) + } + + if (!optvalue || optlen != sizeof(UINT64)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_STOP_TRANSMITTING_ADU ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(UINT64))) + goto error; + } + + if (mclcb->tx.is_in_keep_data_mode() == true){ + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_STOP_TRANSMITTING_ADU ERROR: not supported in KEEP_DATA mode\n")) + goto error; + } + + toi = (*(UINT64*)optvalue); + + if (toi<=0) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_STOP_TRANSMITTING_ADU ERROR: toi %d, not a valid value\n", + toi)) + goto error; + } + + if ((adu = mclcb->tx.find_adu(mclcb,toi,-1)) == NULL) { + TRACELVL(5, (mcl_stdout, + "<- mcl_ctl: MCL_OPT_STOP_TRANSMITTING_ADU: ADU already removed\n")) + break; + + } + + /* step O: TODO: transmit B-flag to signal end of object tx */ + + /* first reset the transmission tables, + * then remove the ADU from the tx list and free the ADU, + * and update tx schedule */ + + /* step 1: reset the transmission tables */ + for (lay = 0, tl = mclcb->txlay_tab; + lay < mclcb->max_nb_layers; lay++, tl++) { + + /* delete the old tx tabs, and create new ones */ + if (adu->priority == ADU_NORMAL_PRIO) { + delete tl->tx_tab; + tl->tx_tab = new mcl_tx_tab(); + } + else if (adu->priority == ADU_HIGH_PRIO){ + delete tl->tx_tab_high; + tl->tx_tab_high = new mcl_tx_tab(); + } + } + + /* step 2: remove the ADU from the tx list and free the ADU */ + mclcb->tx.remove_adu(mclcb, adu); + mcl_tx_free_this_adu(mclcb, adu); + free(adu); + + /* step 3: update tx schedule */ + if (mclcb->tx.is_in_keep_data_mode() == false) { + UpdateTxPlanning(mclcb,mclcb->tx.get_first_adu(mclcb),mclcb->tx.get_last_adu(mclcb)); + } +#if 0 + else + { + /* As it is implemented at the moment it is as if we are making a PUSH, this is not + * the expected behavior.*/ + /* TODO: Normally we should send everything except all ADUs after the last KEEP */ + UpdateTxPlanning(mclcb,mclcb->tx.get_first_adu(mclcb),mclcb->tx.get_last_adu(mclcb)); + + } +#endif + + + TRACELVL(5, (mcl_stdout, + "<- mcl_ctl: MCL_OPT_STOP_TRANSMITTING_ADU\n")) + + break; + } + + case MCL_OPT_RESET_TRANSMISSIONS: { + /* Delete and free all transmission tables and their ADUs */ + TRACELVL(5, (mcl_stdout, + "-> mcl_ctl: MCL_OPT_RESET_TRANSMISSIONS\n")) + + INT32 lay; + txlay_t *tl; + + if (mclcb->is_a_sender() == false) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_RESET_TRANSMISSIONS ERROR: only possible in SENDER mode\n")) + goto error; + } + + adu_t *new_adu = NULL; + adu_t *adu_list = NULL; + + + /* Go through all layers, remove the adu from their tx_tab, + * and keep in mind (in the adu_list) the removed adus + * (they will all be freed in the next step) */ + + for (lay = 0, tl = mclcb->txlay_tab; + lay < mclcb->max_nb_layers; lay++, tl++) { + tl->tx_tab->remove_all_adu_from_txtab(mclcb, &adu_list); + tl->tx_tab_high->remove_all_adu_from_txtab(mclcb, &adu_list); + + /* delete the old tx tabs, and create new ones */ + delete tl->tx_tab; + delete tl->tx_tab_high; + tl->tx_tab = new mcl_tx_tab(); + tl->tx_tab_high = new mcl_tx_tab(); + } + + /* Now free the adus */ + while(adu_list != NULL) + { + new_adu = adu_list; + mcl_remove_adu (mclcb, new_adu, &adu_list); + mcl_tx_free_this_adu(mclcb, new_adu); + free(new_adu); + } + + mclcb->fsm.update_tx_state(mclcb, TEVENT_RESET); + TRACELVL(5, (mcl_stdout, + "<- mcl_ctl: MCL_OPT_RESET_TRANSMISSIONS\n")) + break; + } + +#ifdef SVSOA_RECV + case MCL_OPT_SET_RX_LEVEL: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_RX_LEVEL ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(UINT32))) + goto error; + } + if (*(int*)optvalue > MAX_NB_TX_LAYERS){ + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_RX_LEVEL ERROR: nb of layer specified to high (got %d, max %d)\n", + *(int*)optvalue, MAX_NB_TX_LAYERS)) + goto error; + } + if (mclcb->is_a_sender()) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_RX_LEVEL ERROR: only possible in RECEIVER mode\n")) + goto error; + } + + mclcb->nb_layers = *(int*)optvalue; + + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_RX_LEVEL (%d)\n", *(int*)optvalue)) + break; + + case MCL_OPT_GET_RX_LEVEL: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_GET_RX_LEVEL ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(UINT32))) + goto error; + } + if (mclcb->is_a_sender()) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_GET_RX_LEVEL ERROR: only possible in RECEIVER mode\n")) + goto error; + } + *(int*)optvalue = mclcb->nb_layers; + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_GET_RX_LEVEL (%d)\n", *(int*)optvalue)) + break; + + case MCL_USED_FOR_BASE_VIDEO_LAYER: + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_BASE_VIDEO_LAYER\n")) +#ifdef ANTICIPATED_TX_FOR_PUSH + mclcb->anticipated_tx_for_push = 1; +#endif + break; +#endif // SVSOA_RECV + + case MCL_OPT_REUSE_APPLI_TX_BUFFER: { + bool val; + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_REUSE_APPLI_TX_BUFFER ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + if (*(int*)optvalue == 0) { + val = false; + } else if (*(int*)optvalue == 1) { + val = true; + } else { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_REUSE_APPLI_TX_BUFFER ERROR: arg %d out of range (0/1)\n", + *(int*)optvalue)) + goto error; + } + mclcb->tx.set_reuse_appli_buf_bool(val); + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_REUSE_APPLI_TX_BUFFER (%d)\n", val)) + break; + } + +#ifdef VIRTUAL_TX_MEM + case MCL_OPT_VIRTUAL_TX_MEMORY: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_VIRTUAL_TX_MEMORY ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + mclcb->vtm_used = *(int*)optvalue; + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_VIRTUAL_TX_MEMORY (%d)\n", + mclcb->vtm_used)) + if (mclcb->vtm_used != 0 && mclcb->vtm_used != 1) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_VIRTUAL_TX_MEMORY ERROR: %d invalid (expected 0 or 1)\n", mclcb->vtm_used)) + mclcb->vtm_used = 0; + goto error; + } + break; +#endif /* VIRTUAL_TX_MEM */ + + case MCL_OPT_VIRTUAL_RX_MEMORY: + bool set; +#ifdef VIRTUAL_RX_MEM + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_VIRTUAL_RX_MEMORY ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + set = *(int*)optvalue; + if (set != 0 && set != 1) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_VIRTUAL_RX_MEMORY ERROR: %d invalid (expected 0 or 1)\n", set)) + goto error; + } + mclcb->rx_storage.set_vrmem(mclcb, (set ? true : false)); + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_VIRTUAL_RX_MEMORY (%d)\n", + (INT32)mclcb->rx_storage.is_vrmem_used())) + break; +#else /* !VIRTUAL_RX_MEM */ + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_VIRTUAL_RX_MEMORY (%d) ignored\n")) + break; +#endif /* VIRTUAL_RX_MEM */ + + case MCL_OPT_DELIVERY_MODE: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_DELIVERY_MODE ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + mclcb->delivery_mode = *(int*)optvalue; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_DELIVERY_MODE (%d)\n", mclcb->delivery_mode)) + if (mclcb->delivery_mode < DEL_MODE_PUSH || + mclcb->delivery_mode > DEL_MODE_STREAMING) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_DELIVERY_MODE ERROR: delivery_mode arg %d out of range ([0; 2])\n", + mclcb->delivery_mode)) + mclcb->delivery_mode = DEL_MODE_PUSH; + goto error; + } +#ifdef ANTICIPATED_TX_FOR_PUSH + if (mclcb->delivery_mode == DEL_MODE_PUSH) { + mclcb->anticipated_tx_for_push = 1; /* usefull here */ + } else { + mclcb->anticipated_tx_for_push = 0; /* useless otherw */ + } +#endif /* ANTICIPATED_TX_FOR_PUSH */ + break; + + case MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + if (*(int*)optvalue == 1) { /* true */ + if (mclcb->rx_window.set_delivery_mode_to_appli(mclcb, + MCL_IMMEDIATE_DELIVERY) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI ERROR: set_delivery_mode_to_appli() failed\n")) + goto error; + } + } else { /* false */ + if (mclcb->rx_window.set_delivery_mode_to_appli(mclcb, + MCL_ORDERED_DELIVERY) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI ERROR: set_delivery_mode_to_appli() failed\n")) + goto error; + } + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI (%d)\n", + mclcb->rx_window.get_delivery_mode_to_appli(mclcb))) + break; + + case MCL_OPT_GET_ADU_RX_INFO: { + mcl_adu_rx_info_t *infop; /* in/out: info structure */ + UINT32 toi; + adu_t *adu; + if (!optvalue || optlen != sizeof(mcl_adu_rx_info_t)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_GET_ADU_RX_INFO ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + infop = (mcl_adu_rx_info_t*)optvalue; + toi = (UINT32)infop->toi; + adu = mclcb->rx_window.find_adu(mclcb, toi, 0); + if (adu == NULL) { + TRACELVL(1, (mcl_stdout, + "mcl_ctl: MCL_OPT_GET_ADU_RX_INFO Warning: ADU (toi=%lu) not found\n", toi)) + goto error; + } else { /* false */ + infop->len = adu->len; + infop->recvd_src_data = adu->recvd_src_data; + infop->rx_status = adu->rx_status; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_GET_ADU_RX_INFO (%lu)\n", toi)) + break; + } + case MCL_OPT_SET_FTI_INFO: + hdr_infos_t hdr_infos; + FTI_infos_t *fti_infop; + if (!optvalue || optlen != sizeof(FTI_infos_t)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FTI_INFO ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + fti_infop = (FTI_infos_t*)optvalue; + + memset(&hdr_infos, 0, sizeof(hdr_infos)); + hdr_infos.idf_adu = fti_infop->toi; + hdr_infos.fec_encoding_id = fti_infop->fec_encoding_id; + hdr_infos.fec_instance_id = fti_infop->fec_instance_id; +#ifdef LDPC_FEC + hdr_infos.fec_key = fti_infop->fec_key; +#endif + hdr_infos.adu_len = fti_infop->adu_len; + hdr_infos.max_k = fti_infop->max_k; + hdr_infos.max_n = fti_infop->max_n; + hdr_infos.symbol_len = fti_infop->symbol_len; + + if (mcl_process_sig (mclcb,EXT_FTI,&hdr_infos,NULL)<0) + { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FTI_INFO ERROR: mcl_process_sig failed\n")) + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_FTI_INFO (%lu)\n", fti_infop->toi)) + + + break; + + case MCL_OPT_SET_FLUTE_STORE_ALL_ADUS_BY_DEFAULT: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FLUTE_STORE_ALL_ADUS_BY_DEFAULT ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + if (mclcb->rx_flute.set_flute_store_all_adus_by_default(mclcb, (bool) optvalue) + == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FLUTE_ALL_ADUS_DELIVERY_TO_APPLI ERROR: set_flute_delivery_mode_to_appli() failed\n")) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_FLUTE_ALL_ADUS_DELIVERY_TO_APPLI\n")) + break; + +#if 0 + case MCL_OPT_SET_FLUTE_SELECTED_ADUS_DELIVERY_TO_APPLI: + if (optvalue || optlen != 0) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FLUTE_SELECTED_ADUS_DELIVERY_TO_APPLI ERROR: no argument needed)\n")) + goto error; + } + if (mclcb->rx_flute.set_flute_delivery_mode_to_appli + (mclcb, MCL_FLUTE_SELECTED_ADUS_DELIVERY) + == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FLUTE_SELECTED_ADUS_DELIVERY_TO_APPLI ERROR: set_flute_delivery_mode_to_appli() failed\n")) + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_SET_FLUTE_SELECTED_ADUS_DELIVERY_TO_APPLI set\n")) + break; +#endif + case MCL_OPT_FLUTE_DELIVER_THIS_ADU_TO_APPLI: + if (!optvalue || optlen != sizeof(UINT32)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_DELIVER_THIS_ADU_TO_APPLI ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(UINT32))) + goto error; + } + if (mclcb->rx_flute.add_requested_toi(mclcb,*(UINT32*)optvalue) + == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_DELIVER_THIS_ADU_TO_APPLI ERROR: add_requested_toi() failed\n")) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_DELIVER_THIS_ADU_TO_APPLI (%d)\n", + *(UINT32*)optvalue)) + break; + + case MCL_OPT_POSTPONE_FEC_DECODING: +#ifdef RSE_FEC + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + if (*(int*)optvalue < 0 || *(int*)optvalue > 1) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING ERROR: arg %d out of range (0/1)\n", + *(int*)optvalue)) + goto error; + } + mclcb->postpone_fec_decoding = *(int*)optvalue; + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING (%d)\n", + mclcb->postpone_fec_decoding)) +#else /* !RSE_FEC */ + /* not critical, avoid a warning if DEBUG not set */ + TRACELVL(1, (mcl_stderr, + "mcl_ctl: MCL_OPT_POSTPONE_FEC_DECODING ERROR: only valid with RSE, doesn't apply to LDPC\n")) + goto error; +#endif /* RSE_FEC */ + break; + + case MCL_OPT_NEVER_LEAVE_BASE_LAYER: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_NEVER_LEAVE_BASE_LAYER ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + if (*(int*)optvalue < 0 || *(int*)optvalue > 1) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_NEVER_LEAVE_BASE_LAYER ERROR: arg %d out of range (0/1)\n", + mclcb->rx.never_leave_base_layer)) + mclcb->rx.never_leave_base_layer = false; + goto error; + } + mclcb->rx.never_leave_base_layer = *(bool*)optvalue; + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_NEVER_LEAVE_BASE_LAYER (%d)\n", + mclcb->rx.never_leave_base_layer)) + break; + + case MCL_OPT_FEC_RATIO: + if (!optvalue || optlen != sizeof(float)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_FEC_RATIO ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(float))) + goto error; + } + if (mclcb->fec.set_fec_ratio(mclcb, *(float*)optvalue) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_FEC_RATIO failed for fec_ratio %f\n", + *(float*)optvalue)) + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_FEC_RATIO (%f)\n", + mclcb->fec.get_fec_ratio())) + break; + + case MCL_OPT_NB_OF_TX: /* send DUs that number of times on base layer*/ + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_NB_OF_TX ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + mclcb->nb_tx = *(int*)optvalue; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_NB_OF_TX (%d)\n", mclcb->nb_tx)) + if (mclcb->nb_tx <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_NB_OF_TX ERROR: %d invalid (expected > 0)\n", mclcb->nb_tx)) + mclcb->nb_tx = 1; + goto error; + } + break; + + case MCL_OPT_ADD_NB_OF_TX: { /* send DUs that number of times on base layer*/ + + int lay; /* layer nb */ + txlay_t *tl; + + + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_ADD_NB_OF_TX ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + + if (*(int*)optvalue <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_ADD_NB_OF_TX ERROR: %d invalid (expected > 0)\n", mclcb->nb_tx)) + goto error; + } + + mclcb->nb_tx += *(int*)optvalue; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_ADD_NB_OF_TX (%d)\n", *(int*)optvalue)) + + for (lay = 0, tl = mclcb->txlay_tab; lay < mclcb->max_nb_layers; + lay++, tl++) { + + tl->tx_tab->add_tx_cycles(mclcb, *(int*)optvalue); + tl->tx_tab_high->add_tx_cycles(mclcb, *(int*)optvalue); + + } + + break; + } + + case MCL_OPT_SCHED: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SCHED ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } +#ifdef LCT_SCHED1 + if (*(int*)optvalue == MCL_SCHED_LCT1) { + mclcb->scheduler = MCL_SCHED_LCT1; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_SCHED (sched1)\n")) + break; + } +#endif +#ifdef LCT_SCHEDSTREAM + if (*(int*)optvalue == MCL_SCHED_LCTSTREAM) { + mclcb->scheduler = MCL_SCHED_LCTSTREAM; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_SCHED (sched_stream)\n")) + break; + } +#endif + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SCHED ERROR: arg %d unsupported\n", + *(int*)optvalue)) + goto error; + + case MCL_OPT_OBJ_SCHED: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_OBJ_SCHED ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + mclcb->adu_scheduling = *(int*)optvalue; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_OBJ_SCHED: %d\n", + mclcb->adu_scheduling)) + if (mclcb->adu_scheduling < 0 || + mclcb->adu_scheduling > MCL_SCHED_MIXED_ORDER) { + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_SCHED ERROR: bad value, must be in range {0..%d}\n", MCL_SCHED_MIXED_ORDER)) + mclcb->adu_scheduling = 0; + goto error; + } + break; + + case MCL_OPT_SET_CC_SCHEME: /* set the CC scheme to be used */ + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_CC_SCHEME ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + + mclcb->congestion_control = (* (mcl_congestion_control_scheme*)optvalue); + + if (mclcb->congestion_control == NO_CC) + { + mclcb->nb_layers = 1; /* 1 layer only! */ + mclcb->max_nb_layers = 1; /* 1 layer only! */ + mclcb->scheduler = MCL_SCHED_LCT1; /* mix everything */ + mclcb->single_layer_mode = true; + } +#ifdef RLC + if (mclcb->congestion_control == RLC_CC) + { + mclcb->scheduler = MCL_SCHED_LCT1; /* mix everything */ + mclcb->single_layer_mode = false; + rlc_init_session(mclcb); + + } +#endif +#ifdef FLIDS + if (mclcb->congestion_control == FLID_SL_CC) + { + mclcb->scheduler = MCL_SCHED_LCT1; /* mix everything */ + mclcb->single_layer_mode = false; + FLIDs_InitSession(mclcb); + } +#endif + + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_SET_CC_SCHEME: %d\n", *(int*)optvalue)) + + break; + + case MCL_OPT_SET_FEC_CODE: /* set the FEC codec to be used */ + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FEC_CODE ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + if (mclcb->fec.set_fec_code(mclcb, (*(int*)optvalue)) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FEC_CODE WARNING: fec.set_fec_code(%d) failed\n", + (*(int*)optvalue))) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_FEC_CODE (%d)\n", (*(int*)optvalue))) + break; + + case MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(UINT32))) + goto error; + } + *(int*)optvalue = mclcb->fec.get_k() * mclcb->get_payload_size(); + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC (%d)\n", + (*(int*)optvalue))) + break; + + default: + opt_found = 0; +#ifdef RLC + if (mclcb->congestion_control == RLC_CC) + { + if (rlc_ctl( mclcb, optname, optvalue, optlen) == MCL_OK) { + opt_found = 1; + } + } +#endif +#ifdef FLIDS + if (mclcb->congestion_control == FLID_SL_CC) + { + if (FLIDs_ctl( mclcb, optname, optvalue, optlen) == MCL_OK) { + opt_found = 1; + } + } +#endif + if (!opt_found) { + PRINT_ERR((mcl_stderr, "mcl_ctl: ERROR: unknown optname %d\n", optname)) + PRINT_ERR((mcl_stderr, "Check that the MCL lib has been compiled with the appropriate flags...\n")) + goto error; + } + break; + + } + TRACELVL(5, (mcl_stdout, "<- mcl_ctl2: ok\n")) + return 0; + +error: + TRACELVL(5, (mcl_stdout, "<- mcl_ctl2: error\n")) + return -1; +} + + +/** + * mcl_send. + * => See header file for more informations. + */ +int +mcl_send (int id, + const void *data, + int len) +{ + INT32 result; + mcl_cb *mclcb; + struct mcl_iovec iov; + struct mcl_msghdr msg; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_send: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + /* + * create a corresponding msg descriptor. + */ + memset((void*)&iov, 0, sizeof(iov)); + memset((void*)&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + iov.iov_type = MCL_IOV_TYPE_BUFFER; + iov.iov_base = (void*)data; + iov.iov_len = len; + result = (INT32)mcl_sendmsg2(mclcb, &msg, MCL_MSG_DEFAULT); + mclcb->unlock(); + return result; +} + + +/** + * mcl_sendto. + * => See header file for more informations. + */ +int +mcl_sendto (int id, + const void *data, + int len, + const struct sockaddr *saddr, + int saddr_len) +{ + INT32 result; + mcl_cb *mclcb; + struct mcl_iovec iov; + struct mcl_msghdr msg; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_sendto: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + /* + * create a corresponding msg descriptor. + */ + memset((void*)&iov, 0, sizeof(iov)); + memset((void*)&msg, 0, sizeof(msg)); + if (saddr) { + msg.msg_name = (void*)saddr; + msg.msg_namelen = saddr_len; /* will be checked later */ + } else { + msg.msg_name = NULL; + msg.msg_namelen = 0; + } + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + iov.iov_type = MCL_IOV_TYPE_BUFFER; + iov.iov_base = (void*)data; + iov.iov_len = len; + result = (INT32)mcl_sendmsg2(mclcb, &msg, MCL_MSG_DEFAULT); + mclcb->unlock(); + return result; +} + +#if 0 + +/** + * mcl_sendto2. + * => See header file for more informations. + */ +int +mcl_sendto2 (mcl_cb *const mclcb, + const void *data, + int len, + const struct sockaddr *saddr, + int saddr_len) +{ + INT32 result; + struct mcl_iovec iov; + struct mcl_msghdr msg; + + /* + * create a corresponding msg descriptor. + */ + memset((void*)&iov, 0, sizeof(iov)); + memset((void*)&msg, 0, sizeof(msg)); + if (saddr) { + msg.msg_name = (void*)saddr; + msg.msg_namelen = saddr_len; /* will be checked later */ + } else { + msg.msg_name = NULL; + msg.msg_namelen = 0; + } + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + iov.iov_type = MCL_IOV_TYPE_BUFFER; + iov.iov_base = (void*)data; + iov.iov_len = len; + result = (INT32)mcl_sendmsg2(mclcb, &msg, MCL_MSG_DEFAULT); + return result; + +#if 0 + adu_t *adu; /* DU descriptor of the data buffer */ +#ifdef FEC + block_t *blk; + int i; +#endif /* FEC */ + UINT32 padded_len; /* size with padding to 0 for FEC */ + int tot_fec_nb = 0; /* fec DUs created by mcl_fec_encode */ +#ifdef ANTICIPATED_TX_FOR_PUSH + int try_2_send_count = 4; /* period between 2 attempts */ +#endif + + TRACELVL(5, (mcl_stdout, "-> mcl_sendto: len=%d, saddr_len=%d\n", + len, saddr_len)) +#ifdef SVSOA_RECV + mclcb->finish_session_init_if_needed(1); +#else + mclcb->finish_session_init_if_needed(); +#endif + if (data == NULL && len == 0) { + /* + * the appli issued this call just to finish the init... + * nothing else to do, return. + */ + TRACELVL(5, (mcl_stdout, "<- mcl_sendto: no data, return\n")) + goto end; + } + +#ifdef METAOBJECT_USED + /* check if we are sending a meta object */ + if (mclcb->meta_obj_layer->in_use() == true && + mclcb->meta_obj_layer->completed == false) { + if (mclcb->meta_obj_layer->add_object((char *)data, len) >= 0) { + goto end; + } else { + goto error; + } + } +#endif + + mclcb->fsm.update_tx_state(mclcb, TEVENT_NEW_ADU); + if (mclcb->fsm.can_send_data(mclcb) == false) { + TRACELVL(5, (mcl_stdout, "<- mcl_sendto: ERROR, cannot send\n")) + goto error; + } + if (!data || len <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: data arg NULL or len arg <= 0\n")) + goto error; + } + if (saddr && (saddr_len != sizeof(struct sockaddr_in) + saddr_len != sizeof(struct sockaddr_in6))) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: saddr != NULL and bad saddr_len arg (only %d/%d possible, got %d)\n", + sizeof(struct sockaddr_in), + sizeof(struct sockaddr_in6), saddr_len)) + goto error; + } + + /* + * Create the ADU descriptor... + */ + adu = mcl_create_adu(mclcb); + adu->fec_scheme = mclcb->fec.get_fec_code(); + if (mclcb->fec.scheme_to_enc_inst(mclcb, adu->fec_scheme, + &(adu->fec_encoding_id), + &(adu->fec_instance_id)) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: unsupported FEC scheme %d\n", + adu->fec_scheme)) + goto error; + } + adu->len = len; + if (saddr_len > 0) { + /* remember the dest addr to use (rather than default dest) */ + if (saddr_len == sizeof(struct sockaddr_in)) { + adu->addr.set_addr_struct((struct sockaddr_in*)saddr); + } else { + adu->addr.set_addr_struct((struct sockaddr_in6*)saddr); + } + adu->addr_valid = true; + } + adu->seq = mclcb->tx.get_next_toi(); + /* by default, unless the appli specifies a new TOI, next ADU will + * use this one... */ + mclcb->tx.incr_next_toi(); + /* set the importance of the ADU */ + if (mclcb->tx.next_adu_is_of_high_prio == true) { + adu->priority = ADU_HIGH_PRIO; + /* reset for next ADU */ + mclcb->tx.next_adu_is_of_high_prio = false; + } else { + adu->priority = ADU_NORMAL_PRIO; + } + + /* all DUs for this ADU have this size */ + adu->symbol_len = mclcb->get_payload_size(); + if (mclcb->is_flute_compatible() +#ifdef METAOBJECT_USED + || (mclcb->meta_obj_layer->in_use() == true) +#endif + ) { + if (adu->seq == 0) { + /* FDT */ + adu->FDT_instanceid = + mclcb->tx_flute.get_next_FDT_instanceID(); + mclcb->tx_flute.incr_next_FDT_instanceID(); + } else { + adu->FDT_instanceid = 0; // XXX: TODO... + } + } + /* + * insert it in the transmission ADU list... + */ + mclcb->tx.insert_adu(mclcb, adu); + /* + * store the application data... + */ + padded_len = (UINT32)(ceil((double)len / (double)adu->symbol_len) + * (double)adu->symbol_len); + adu->padded_len = padded_len; +#ifdef VIRTUAL_TX_MEM + if (mcl_vtm_can_store_in_vtm(mclcb, padded_len)) { + /* + * use the VTMEM service to register data + */ + if (mcl_vtm_store_data(mclcb, adu, NULL, (char*)data, len, padded_len) ) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: Virtual Tx Memory service failed\n")) + goto error; + } + if (mclcb->tx.can_reuse_appli_buf()) { + /* + * free the data buffer. + * In fact using reuse_appli is here useless! + */ + free((void*)data); + PRINT_ERR((mcl_stderr, "mcl_sendto: WARNING: using reuse_appli_tx_buffer is useless in Virtual Tx Memory mode\n")) + } + } else { + /* + * store in physical tx memory (ptm) + */ +#endif /* VIRTUAL_TX_MEM */ + if (mclcb->tx.can_reuse_appli_buf()) { + /* take control of buf and avoid an extra data copy */ + if (padded_len != len) { + /* add a null padding to end of block */ + if (!(adu->data = (char*)realloc((void*)data, padded_len))) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: out of memory\n")) + goto error; + } + memset(adu->data + len, 0, padded_len - len); + } + } else { + if (!(adu->data = (char*)malloc(padded_len))) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: out of memory\n")) + goto error; + } + memcpy(adu->data, data, len); + memset(adu->data + len, 0, padded_len - len);/*padding*/ + /*PRINT_OUT((mcl_stdout, + "copied data to x%x, len=%d, padded_len=%d\n", + (int)adu->data, len, padded_len))*/ + } +#ifdef VIRTUAL_TX_MEM + if (mclcb->vtm_used) { + /* remember it kept in physical memory */ + mcl_vtm_register_in_ptm(mclcb, adu, NULL, padded_len); + } + } +#endif /* VIRTUAL_TX_MEM */ + /* + * segment it... + */ + mcl_tx_segment_adu(mclcb, adu); +#ifdef FEC + /* + * create additional FEC DUs for each block... + */ + for (i = adu->blocking_struct.block_nb, blk = adu->block_head; i > 0; i--, blk++) { + tot_fec_nb += mclcb->fec.encode(mclcb, blk); + /*PRINT_OUT((mcl_stdout, + "tot_fec_nb=%d, blk->k=%d, blk->fec_nb=%d \n", + tot_fec_nb, blk->k, blk->fec_du_nb_in_list))*/ +#ifdef ANTICIPATED_TX_FOR_PUSH + if (mclcb->anticipated_tx_for_push) { + if (--try_2_send_count <= 0) { + try_2_send_count = 4; + /* now try to send */ + mclcb->periodic_proc.do_periodic_proc(mclcb); + } + } +#endif + } +#endif /* FEC */ + /* + * planify transmissions... + */ + if (mclcb->tx.is_in_keep_data_mode()) { + /* + * If we are in KEEP_DATA mode (in that case scheduling + * will be done later when the application issues a PUSH), + * then remember it for a future PUSH... + */ + mclcb->tx.register_adu_in_keep_data_mode(mclcb, adu); +#ifdef ANTICIPATED_TX_FOR_PUSH + if (mclcb->anticipated_tx_for_push && + (mclcb->is_flute_compatible() == false)) { + /* update tx planning for anticipated tx in push mode + * unless we are in FLUTE mode */ + TRACELVL(5, (mcl_stdout, + " mcl_sendto: anticipated tx of adu")) + AnticipTx_UpdateTxPlanning(mclcb, adu); + /* and now try to send */ + mclcb->periodic_proc.do_periodic_proc(mclcb); + } +#endif /* ANTICIPATED_TX_FOR_PUSH */ + } else { + /* + * We are not in KEEP_DATA mode. + */ + UpdateTxPlanning(mclcb, adu, adu); + } + mclcb->tx.there_is_more_to_tx = true; + /* + * update stats + */ + mclcb->stats.adus_announced++; + mclcb->stats.buf_space += padded_len + tot_fec_nb * adu->symbol_len; + if (mclcb->stats.buf_space > mclcb->stats.max_buf_space) + mclcb->stats.max_buf_space = mclcb->stats.buf_space; + if (mclcb->get_stats_level() > 0) + mcl_print_tx_stats(mclcb); + + TRACELVL(5, (mcl_stdout, "<- mcl_sendto: return %d\n", len)) +end: + return len; + +error: + return -1; +#endif +} + +#endif + +/** + * mcl_sendmsg. + * => See header file for more informations. + */ +INT64 +mcl_sendmsg (int id, + struct mcl_msghdr *msg, + mcl_msgflag flags) +{ + INT64 result; + mcl_cb *mclcb; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_sendmsg: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + result = mcl_sendmsg2(mclcb, msg, flags); + mclcb->unlock(); + return result; +} + + +/** + * mcl_sendmsg2. + * => See header file for more informations. + */ +INT64 +mcl_sendmsg2(mcl_cb *const mclcb, + struct mcl_msghdr *msg, + mcl_msgflag flags) +{ + adu_t *adu; /* DU descriptor of the data buffer */ +#ifdef FEC + block_t *blk; + INT32 i; +#endif /* FEC */ + INT32 tot_fec_nb = 0; /* fec DUs created by mcl_fec_encode */ + struct sockaddr *saddr; /* optional dest addr struct */ + int saddr_len; /* optional dest addr struct length */ +#ifdef ANTICIPATED_TX_FOR_PUSH + int try_2_send_count = 4; /* period between 2 attempts */ +#endif + + TRACELVL(5, (mcl_stdout, "-> mcl_sendmsg2:\n")) +#ifdef SVSOA_RECV + mclcb->finish_session_init_if_needed(1); +#else + mclcb->finish_session_init_if_needed(); +#endif + if (msg == NULL) { + /* + * the appli issued this call just to finish the init... + * nothing else to do, return. + */ + TRACELVL(5, (mcl_stdout, "<- mcl_sendmsg2: no data, return\n")) + goto end; + } + if (flags != MCL_MSG_DEFAULT) { + PRINT_ERR((mcl_stderr, + "mcl_sendmsg2: ERROR: invalid flags (expected %d, got %d)\n", + MCL_MSG_DEFAULT, flags)) + goto error; + } + +#ifdef METAOBJECT_USED + /* check if we are sending a meta object */ + if (mclcb->meta_obj_layer->in_use() == true && + mclcb->meta_obj_layer->completed == false) { + if (mclcb->meta_obj_layer->add_object(msg) >= 0) { + return msg->msg_iov->iov_len; + } else { + goto error; + } + } +#endif + + mclcb->fsm.update_tx_state(mclcb, TEVENT_NEW_ADU); + if (mclcb->fsm.can_send_data(mclcb) == false) { + TRACELVL(5, (mcl_stdout, "<- mcl_sendmsg2: ERROR, cannot send\n")) + goto error; + } + //if (!data || len <= 0) + if ((msg->msg_iov == NULL) || (msg->msg_iovlen <= 0)) { + PRINT_ERR((mcl_stderr, + "mcl_sendmsg2: ERROR: msg->msg_iov NULL or msg->msg_iovlen <= 0\n")) + goto error; + } + saddr = (struct sockaddr*)(msg->msg_name); + saddr_len = msg->msg_namelen; + if (saddr && (saddr_len != sizeof(struct sockaddr_in)) + && (saddr_len != sizeof(struct sockaddr_in6))) { + PRINT_ERR((mcl_stderr, + "mcl_sendmsg2: ERROR: msg->msg_name != NULL and bad msg->msg_namelen arg (only %d/%d possible, got %d)\n", + sizeof(struct sockaddr_in), + sizeof(struct sockaddr_in6), saddr_len)) + goto error; + } + + /* + * Create the ADU descriptor... + */ + adu = mcl_create_adu(mclcb); + adu->fec_scheme = mclcb->fec.get_fec_code(); + if (mclcb->fec.scheme_to_enc_inst(mclcb, adu->fec_scheme, + &(adu->fec_encoding_id), + &(adu->fec_instance_id)) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_sendmsg2: ERROR: unsupported FEC scheme %d\n", + adu->fec_scheme)) + goto error; + } + //adu->len = len; + if (saddr_len > 0) { + /* remember the dest addr to use (rather than default dest) */ + if (saddr_len == sizeof(struct sockaddr_in)) { + adu->addr.set_addr_struct((struct sockaddr_in*)saddr); + } else { + adu->addr.set_addr_struct((struct sockaddr_in6*)saddr); + } + adu->addr_valid = true; + } + adu->seq = mclcb->tx.get_next_toi(); + /* by default, unless the appli specifies a new TOI, next ADU will + * use this one... */ + mclcb->tx.incr_next_toi(); + /* set the importance of the ADU */ + if (mclcb->tx.next_adu_is_of_high_prio == true) { + adu->priority = ADU_HIGH_PRIO; + /* reset for next ADU */ + mclcb->tx.next_adu_is_of_high_prio = false; + } else { + adu->priority = ADU_NORMAL_PRIO; + } + + /* all DUs for this ADU have this size */ + adu->symbol_len = mclcb->get_payload_size(); + if (mclcb->is_flute_compatible() +#ifdef METAOBJECT_USED + || (mclcb->meta_obj_layer->in_use() == true) +#endif + ) { + if (adu->seq == 0) { + /* FDT */ + adu->FDT_instanceid = + mclcb->tx_flute.get_next_FDT_instanceID(); + mclcb->tx_flute.incr_next_FDT_instanceID(); + if (mclcb->tx.is_in_keep_data_mode() == false) + /* TODO: remove the 'if' when MCL_OPT_STOP_TRANSMITTING_ADU is supported in KEEP mode */ + { + /* remove previous ADU with toi == 0 */ + UINT64 toi = 0; + mcl_ctl2(mclcb, MCL_OPT_STOP_TRANSMITTING_ADU, (void*)&toi, sizeof(toi)); + } + + } else { + adu->FDT_instanceid = 0; + } + } + /* + * insert it in the transmission ADU list... + */ + mclcb->tx.insert_adu(mclcb, adu); + /* + * process the iovec structure, calculate the ADU length, and + * store the application data... + */ + if (mclcb->tx.copy_from_iovec_to_adu(mclcb, msg, adu) == MCL_ERROR) { + goto error; + } + /* + * segment it... + */ + mcl_tx_segment_adu(mclcb, adu); +#ifdef FEC + /* + * create additional FEC DUs for each block... + */ + for (i = adu->blocking_struct.block_nb, blk = adu->block_head; + i > 0; i--, blk++) { + tot_fec_nb += mclcb->fec.encode(mclcb, blk); + /*PRINT_OUT((mcl_stdout, + "tot_fec_nb=%d, blk->k=%d, blk->fec_nb=%d \n", + tot_fec_nb, blk->k, blk->fec_du_nb_in_list))*/ +#ifdef ANTICIPATED_TX_FOR_PUSH + if (mclcb->anticipated_tx_for_push) { + if (--try_2_send_count <= 0) { + try_2_send_count = 4; + /* now try to send */ + mclcb->periodic_proc.do_periodic_proc(mclcb); + } + } +#endif + } +#endif /* FEC */ + /* + * planify transmissions... + */ + if (mclcb->tx.is_in_keep_data_mode()) { + /* + * If we are in KEEP_DATA mode, then remember the ADU + * for a future PUSH (here scheduling will be done later + * when the application issues a PUSH). + */ + mclcb->tx.register_adu_in_keep_data_mode(mclcb, adu); +#ifdef ANTICIPATED_TX_FOR_PUSH + if (mclcb->anticipated_tx_for_push && + (mclcb->is_flute_compatible() == false)) { + /* update tx planning for anticipated tx in push mode + * unless we are in FLUTE mode */ + TRACELVL(5, (mcl_stdout, + " mcl_sendmsg2: anticipated tx of adu")) + AnticipTx_UpdateTxPlanning(mclcb, adu); + /* and now try to send */ + mclcb->periodic_proc.do_periodic_proc(mclcb); + } +#endif /* ANTICIPATED_TX_FOR_PUSH */ + } else { + /* + * We are not in KEEP_DATA mode. + */ + UpdateTxPlanning(mclcb, adu, adu); + } + mclcb->tx.there_is_more_to_tx = true; + /* + * update stats + */ + mclcb->stats.adus_announced++; + mclcb->stats.buf_space += adu->padded_len + tot_fec_nb * adu->symbol_len; + if (mclcb->stats.buf_space > mclcb->stats.max_buf_space) + mclcb->stats.max_buf_space = mclcb->stats.buf_space; + if (mclcb->get_stats_level() > 0) + mcl_print_tx_stats(mclcb); + + TRACELVL(5, (mcl_stdout, "<- mcl_sendmsg2: return %d\n", adu->len)) +end: + return adu->len; + +error: + return -1; +} + + +#if 0 +#ifndef SVSOA_RECV //Flute will never be used with SVSOA +/** + * mcl_recv_flute. + * => See header file for more informations. + */ +int +mcl_recv_flute (int id, + void *buf, + int len, + unsigned int *toi) +{ + int saddr_len = 0; + return mcl_recvfrom_flute(id, buf, len, NULL, &saddr_len, toi); +} + + +/** + * mcl_recvfrom_flute. + * => See header file for more informations. + */ +int +mcl_recvfrom_flute (int id, + void *buf, + int len, + struct sockaddr *saddr, + int *saddr_len, + unsigned int *toi) +{ + int rlen; + mcl_cb *mclcb; + struct mcl_iovec iov; + struct mcl_msghdr msg; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_recvfrom_flute: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + TRACELVL(5, (mcl_stdout, "-> mcl_recvfrom: len=%d, saddr_len ptr=x%x\n", + len, (int)saddr_len)) +#ifdef SVSOA_RECV + mclcb->finish_session_init_if_needed(1); +#else + mclcb->finish_session_init_if_needed(); +#endif + if (buf == NULL || len == 0) { + /* + * the appli issued this call just to finish the init... + * nothing else to do, return. + */ + TRACELVL(5, (mcl_stdout, "<- mcl_recvfrom: NULL reception buffer, return\n")) + rlen = 0; + goto end; + } +#if 0 /* can't check because the tx may be finished and the appli */ + /* only retrieves data available... */ + if (mclcb->fsm.can_recv_data(mclcb) == false) { + PRINT_ERR((mcl_stderr, "mcl_recvfrom: ERROR: cannot recv\n")) + goto error; + } +#endif + /* + * create a corresponding msg descriptor. + */ + memset((void*)&iov, 0, sizeof(iov)); + memset((void*)&msg, 0, sizeof(msg)); + if (saddr) { + if (saddr_len == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_recvfrom: ERROR: bad saddr_len arg (NULL pointer)\n")) + goto error; + } + msg.msg_name = saddr; + msg.msg_namelen = *saddr_len; + } else { + msg.msg_name = NULL; + msg.msg_namelen = 0; + } + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + iov.iov_type = MCL_IOV_TYPE_BUFFER; + iov.iov_base = buf; + iov.iov_len = len; + /* + * check if an adu is available and copy it to the application buffer. + * Use polling for the present... + */ + while ((rlen = mclcb->rx_window.return_adu_to_appli(mclcb, &msg, + MCL_MSG_DEFAULT, + toi)) < 0) { + if (mclcb->fsm.no_new_undup_du(mclcb)) { + TRACELVL(5, (mcl_stdout, "<- mcl_recvfrom: closed, return -1\n")) + goto error; + } + /* + * nothing received yet so wait a little bit (polling). + * the waiting time is a compromize... what should we use? + */ + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + if (mclcb->rx_thread == 0) + goto error; + + } + /* + * copy back remote addr if appli is interested + */ + if (saddr) { + *saddr_len = msg.msg_namelen; + } + TRACELVL(5, (mcl_stdout, "<- mcl_recvfrom: return %d\n", rlen)) +end: + mclcb->unlock(); + return rlen; + +error: + mclcb->unlock(); + return -1; +} +#endif /* !SVSOA_RECV */ +#endif + + +/** + * mcl_recv. + * => See header file for more informations. + */ +int +mcl_recv (int id, + void *buf, + int len) +{ + int saddr_len = 0; + return mcl_recvfrom(id, buf, len, NULL, &saddr_len); +} + +/** + * mcl_recvfrom. + * => See header file for more informations. + */ +int +mcl_recvfrom (int id, + void *buf, + int len, + struct sockaddr *saddr, + int *saddr_len) +{ + int rlen = 0; + mcl_cb *mclcb; + struct mcl_iovec iov; + struct mcl_msghdr msg; + unsigned int toi = 0; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_recvfrom: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + TRACELVL(5, (mcl_stdout, "-> mcl_recvfrom: len=%d, saddr_len ptr=x%x\n", + len, (int)saddr_len)) +#ifdef SVSOA_RECV + mclcb->finish_session_init_if_needed(mclcb->nb_layers); +#else + mclcb->finish_session_init_if_needed(); +#endif + if (buf == NULL || len == 0) { + /* + * the appli issued this call just to finish the init... + * nothing else to do, return. + */ + TRACELVL(5, (mcl_stdout, "<- mcl_recvfrom: NULL reception buffer, return\n")) + rlen = 0; + goto end; + } +#if 0 /* can't check because the tx may be finished and the appli */ + /* only retrieves data available... */ + if (mclcb->fsm.can_recv_data(mclcb) == false) { + PRINT_ERR((mcl_stderr, "mcl_recvfrom: ERROR: cannot recv\n")) + goto error; + } +#endif + /* + * create a corresponding msg descriptor. + */ + memset((void*)&iov, 0, sizeof(iov)); + memset((void*)&msg, 0, sizeof(msg)); + if (saddr) { + if (saddr_len == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_recvfrom: ERROR: bad saddr_len arg (NULL pointer)\n")) + goto error; + } + msg.msg_name = saddr; + msg.msg_namelen = *saddr_len; + } else { + msg.msg_name = NULL; + msg.msg_namelen = 0; + } + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + iov.iov_type = MCL_IOV_TYPE_BUFFER; + iov.iov_base = buf; + iov.iov_len = len; + /* + * check if an adu is available and copy it to the application buffer. + * Use polling for the present... + */ +#ifdef METAOBJECT_USED + if (mclcb->meta_obj_layer->in_use() == false) + { +#endif + while ((rlen = mclcb->rx_window.return_adu_to_appli(mclcb, &msg, + MCL_MSG_DEFAULT, &toi)) < 0) + { + if (mclcb->fsm.no_new_undup_du(mclcb)) { + TRACELVL(5, (mcl_stdout, + "<- mcl_recvfrom: closed, return -1\n")) + goto error; + } + /* + * nothing received yet so wait a little bit (polling). + * the waiting time is a compromize... + */ + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + if (mclcb->rx_thread == 0) + goto error; + +#ifdef METAOBJECT_USED + if (mclcb->meta_obj_layer->in_use() == true) + { /* + * We received a packet that indicated the use + * of metaobjects. jump to appropriate loop. + */ + goto meta_object_used; + } +#endif + } + +#ifdef METAOBJECT_USED + if (mclcb->meta_obj_layer->in_use() == true && toi == 0) + { /* + * We received a MODT and a packet that indicated + * the use of metaobjects. + * Pass MODT to the meta object mgmt and jump to + * appropriate loop. + */ + mclcb->meta_obj_layer->add_object_description_table((char*)buf, (u_int)rlen); + goto meta_object_used; + } + } else { + +meta_object_used: + + while (((rlen = mclcb->rx_window.return_adu_to_appli + (mclcb, &msg, MCL_MSG_DEFAULT, &toi)) < 0) + || (toi == 0 && rlen > 0)) + { + if (toi == 0 && rlen > 0) { + /* + * we got a MODT... Pass it to the meta object + * mgmt layer only, but not to the application. + */ + mclcb->meta_obj_layer->add_object_description_table((char*)buf, (u_int)rlen); + } + else if ((rlen = mclcb->meta_obj_layer->check_for_decoded_objects(&msg, MCL_MSG_DEFAULT)) > 0) { + break; + } + else if (mclcb->fsm.no_new_undup_du(mclcb)) { + TRACELVL(5, (mcl_stdout, + "<- mcl_recvfrom: closed, return -1\n")) + goto error; + } + /* + * nothing received yet so wait a little bit (polling). + * the waiting time is a compromize... what should we use? + */ + mclcb->unlock(); + mcl_usleep(MODT_POLLING_PERIOD); + mclcb->lock(); + if (mclcb->rx_thread == 0) + goto error; + } + } +#endif /* METAOBJECT_USED */ + + /* + * copy back remote addr len if appli is interested. + */ + if (saddr) { + *saddr_len = msg.msg_namelen; + } + TRACELVL(5, (mcl_stdout, "<- mcl_recvfrom: return %d\n", rlen)) +end: + mclcb->unlock(); + return rlen; + +error: + mclcb->unlock(); + return -1; +} + + +/** + * mcl_recvmsg extended data reception function. + * => See header file for more informations. + */ +INT64 +mcl_recvmsg (int id, + struct mcl_msghdr *msg, + enum mcl_msgflag flags) +{ + int rlen; + mcl_cb *mclcb; + unsigned int toi = 0; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_recvmsg: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + TRACELVL(5, (mcl_stdout, "-> mcl_recvmsg: \n")) +#ifdef SVSOA_RECV + mclcb->finish_session_init_if_needed(mclcb->nb_layers); +#else + mclcb->finish_session_init_if_needed(); +#endif + if (msg == NULL) { + /* + * the appli issued this call just to finish the init... + * nothing else to do, return. + */ + TRACELVL(5, (mcl_stdout, "<- mcl_recvmsg: NULL reception buffer, return\n")) + rlen = 0; + goto end; + } + /* + * check if an adu is available and copy it to the application buffer. + * Use polling for the present... + */ +#ifdef METAOBJECT_USED + if (mclcb->meta_obj_layer->in_use() == false) { +#endif + while ((rlen = mclcb->rx_window.return_adu_to_appli(mclcb, msg, + flags, &toi)) < 0) + { + if (mclcb->fsm.no_new_undup_du(mclcb)) { + TRACELVL(5, (mcl_stdout, + "<- mcl_recvfrom: closed, return -1\n")) + goto error; + } + /* + * nothing received yet so wait a little bit (polling). + * the waiting time is a compromize... + */ + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + if (mclcb->rx_thread == 0) + goto error; +#ifdef METAOBJECT_USED + if (mclcb->meta_obj_layer->in_use() == true) + { + /* + * We received a packet that indicated the use + * of metaobjects. jump to appropriate loop. + */ + goto meta_object_used; + } +#endif + } +#ifdef METAOBJECT_USED + if (mclcb->meta_obj_layer->in_use() == true && toi == 0) { + /* + * We received a MODT and a packet that indicated the + * use of metaobjects. + * Pass MODT to the meta object mgmt and jump to + * appropriate loop. + * If we are not in MCL_MSG_DEFAULT, the next + * return_adu_to_appli will return the same ADU + * again, and will then be passed to the meta object + * mgmt. + */ + if (flags == MCL_MSG_DEFAULT) + mclcb->meta_obj_layer->add_object_description_table((char*)msg->msg_iov->iov_base, (u_int)rlen); + goto meta_object_used; + } + } else { + +meta_object_used: + while (((rlen = mclcb->rx_window.return_adu_to_appli(mclcb, msg, + flags, &toi)) < 0) + || (toi == 0 && rlen > 0)) + { + if (toi == 0 && rlen > 0) + { + /* + * we got a MODT... Pass it to the meta object + * mgmt layer only, but not to the application. + */ + if (flags != MCL_MSG_DEFAULT) + { + /* object has not been copied, it was only + * a check. So call return_adu_to_appli and + * now copy it */ + char * buf = (char *) malloc(rlen); + struct mcl_msghdr msg2; + struct mcl_iovec iov2; + + /* + * create a corresponding msg descriptor. + */ + msg2.msg_iov = &iov2; + msg2.msg_iovlen = 1; + msg2.msg_name = NULL; + msg2.msg_namelen = 0; + iov2.iov_type = MCL_IOV_TYPE_BUFFER; + iov2.iov_base = buf; + iov2.iov_len = rlen; + iov2.iov_filename = NULL; + iov2.iov_offset = 0; + /* get the MODT now and pass it to the + * meta object mgmt layer */ + mclcb->rx_window.return_adu_to_appli(mclcb, + &msg2, MCL_MSG_DEFAULT, NULL); + mclcb->meta_obj_layer->add_object_description_table((char*)buf, (u_int)rlen); + free(buf); + } + else + { + mclcb->meta_obj_layer->add_object_description_table((char*)msg->msg_iov->iov_base, (u_int)rlen); + } + } + else if ((rlen = mclcb->meta_obj_layer->check_for_decoded_objects(msg, flags)) > 0) { + break; + } + else if (mclcb->fsm.no_new_undup_du(mclcb)) { + TRACELVL(5, (mcl_stdout, + "<- mcl_recvmsg: closed, return -1\n")) + goto error; + } + /* + * nothing received yet so wait a little bit (polling). + * the waiting time is a compromize... + * what should we use? + */ + mclcb->unlock(); + mcl_usleep(MODT_POLLING_PERIOD); + mclcb->lock(); + if (mclcb->rx_thread == 0) + goto error; + } + } +#endif /* METAOBJECT_USED */ + + + TRACELVL(5, (mcl_stdout, "<- mcl_recvmsg: return %d\n", rlen)) +end: + mclcb->unlock(); + return rlen; + +error: + mclcb->unlock(); + return -1; +} + + +/** + * mcl_wait_event waits (i.e. blocks) until a given event takes + * place and then returns. + * => See header file for more informations. + */ +int +mcl_wait_event (int id, + int event) +{ + mcl_cb *mclcb; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_wait_event: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + switch(event) { + case MCL_WAIT_EVENT_END_TX: + /* + * wait untill all DUs have been sent + */ + if (mclcb->is_a_sender() == false) { + PRINT_ERR((mcl_stderr, + "mcl_wait_event: MCL_WAIT_EVENT_END_TX, ERROR, id %d isn't sender\n", id)) + goto error; + } + while (mclcb->tx.there_is_more_to_tx) { + TRACELVL(5, (mcl_stdout, " mcl_wait_event: MCL_WAIT_EVENT_END_TX, wait a bit...\n")) + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + } + break; + + case MCL_WAIT_EVENT_END_RX: + /* + * wait untill a sufficient number of DUs have been received + * to complete all ADUs + */ + if (mclcb->is_a_receiver() == false) { + PRINT_ERR((mcl_stderr, + "mcl_wait_event: MCL_WAIT_EVENT_END_RX, ERROR, id %d isn't receiver\n", id)) + goto error; + } + while (!mclcb->fsm.no_new_undup_du(mclcb)) { + TRACELVL(5, (mcl_stdout, " mcl_wait_event: MCL_WAIT_EVENT_END_RX, wait a bit...\n")) + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + } + break; + + case MCL_WAIT_EVENT_CLOSED: + /* + * wait untill we receive a CLOSE message from source, + * indicating that all DUs have been sent... + */ + if (mclcb->is_a_receiver() == false) { + PRINT_ERR((mcl_stderr, + "mcl_wait_event: MCL_WAIT_EVENT_CLOSED, ERROR, id %d isn't receiver\n", id)) + goto error; + } + /* + * NB: it requires that the receiver continues to receive + * DUs, even after the completion of all the ADUs, so don't + * leave layer 0 otherwise the CLOSE messages may be lost... + */ + if (!mclcb->rx.never_leave_base_layer) { + PRINT_ERR((mcl_stderr, + "mcl_wait_event: MCL_WAIT_EVENT_CLOSED, ERROR, use NEVER_LEAVE_BASE_LAYER option first\n")) + goto error; + } + while (!mclcb->fsm.close_already_rx(mclcb)) { + TRACELVL(5, (mcl_stdout, " mcl_wait_event: MCL_WAIT_EVENT_CLOSED, wait a bit...\n")) + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + } + break; + + default: + PRINT_ERR((mcl_stderr, + "mcl_wait_event: ERROR, unknown event %d\n", event)) + goto error; + } + mclcb->unlock(); + return 0; + +error: + mclcb->unlock(); + return -1; +} + + +/* + * mcl_select + * + * WARNING: this is a limited version of mcl_select that only accepts + * a single MCL fd of read type, with a timeout. + * All uses with several readfds, a non null writefds or exceptfds + * will fail. + * + * params : same at the Socket select() syscall + * + * return : same at the Socket select() syscall + * WARNING: the timeout parameter is undefined after calling + * mcl_select, do not assume linux' select(2) like behaviour + * concerning timeout... + */ +int +mcl_select (int n, + fd_set *readfds, + fd_set *writefds, + fd_set *exceptfds, + struct timeval *timeout) +{ + mcl_cb *mclcb; + int id; /* readfd of interest (there should be only 1)*/ + int rlen; + struct timeval begin; /* time starts here... */ + struct timeval end; /* ...and stops here */ + struct timeval cur; /* current time to compare with end */ + struct mcl_msghdr msg; /* needed by mcl_recvmsg */ + + if (writefds != NULL || exceptfds != NULL) { + PRINT_ERR((mcl_stderr, + "mcl_select: ERROR, non NULL writefds or exceptfds not supported\n")) + return -1; + } + if (readfds == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_select: ERROR, NULL readfs not supported\n")) + return -1; + } + if (timeout) { + /* sanity checks */ + if (timeout->tv_sec < 0 || timeout->tv_usec < 0 || + timeout->tv_usec >= 1000000) { + PRINT_ERR((mcl_stderr, + "mcl_select: ERROR, invalid timeout value\n")) + return -1; + } + /* calculate timeout date */ + mcl_gettimeofday(&begin); + end.tv_usec = (begin.tv_usec + timeout->tv_usec) % 1000000; + end.tv_sec = begin.tv_sec + timeout->tv_sec + + (begin.tv_usec + timeout-> tv_usec) / 1000000; + } +#ifdef DEBUG + /* check there is a single fd set in readfds */ +#endif + id = n - 1; + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_select: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + /* + * since the problem is to wait at most timeout until a new ADU + * is available on this session, we can reuse the mcl_recvfrom + * code, with the only exception that we don't read data from + * the incoming list, just check if there is some available. + */ + TRACELVL(5, (mcl_stdout, "-> mcl_select: watch mclcb=x%x\n", (int)mclcb)) +#ifdef SVSOA_RECV + mclcb->finish_session_init_if_needed(1); +#else + mclcb->finish_session_init_if_needed(); +#endif + +#if 0 + if (!mclcb->initialized) { +#ifdef SVSOA_RECV + mcl_end_init_mclcb(mclcb, 1); +#else + mcl_end_init_mclcb(mclcb); +#endif + } +#endif + /* + * check if an adu is available without removing it from MCL's + * incoming list (use NULL buffer/ 0 len for that). + * XXX : use polling for the present... change it! + */ + /* create a corresponding msg descriptor */ + memset((void*)&msg, 0, sizeof(msg)); + while ((rlen = mclcb->rx_window.return_adu_to_appli(mclcb, &msg, + MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT, + 0)) < 0) { + if (mclcb->fsm.no_new_undup_du(mclcb)) { + TRACELVL(5, (mcl_stdout, "<- mcl_recvfrom: closed, return -1\n")) + return 0; + } + /* + * check if we can afford to wait some more... + */ + if (timeout) { + mcl_gettimeofday(&cur); + if (cur.tv_sec > end.tv_sec || + (cur.tv_sec == end.tv_sec && + cur.tv_usec > end.tv_usec)) { + TRACELVL(5, (mcl_stdout, "<- mcl_select: timeout\n")) + mclcb->unlock(); + return 0; + } + } else { + TRACELVL(5, (mcl_stdout, "<- mcl_select: nothing available\n")) + mclcb->unlock(); + return 0; + } + /* + * nothing received yet so wait a little bit (polling). + * the waiting time is a compromize... what should we use? + */ + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + } + ASSERT(rlen == 0); + TRACELVL(5, (mcl_stdout, "<- mcl_select: new ADU available\n")) + mclcb->unlock(); + return 1; +} + diff --git a/src/alc/mcl_lib.h b/src/alc/mcl_lib.h new file mode 100644 index 0000000..5986eeb --- /dev/null +++ b/src/alc/mcl_lib.h @@ -0,0 +1,59 @@ +/* $Id: mcl_lib.h,v 1.2 2005/01/11 15:40:16 moi Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * Private versions of some public functions. + * Differ from the fact that they can be called while being already locked. + */ + +/** + * Internal MCLv3 control function. + * Assumes the caller is already locked. + * Uses the same parameters and return value as mcl_ctl(). + */ +extern int mcl_ctl2 (class mcl_cb *const mclcb, + INT32 optname, + void *optvalue, + INT32 optlen); + +#if 0 +/** + * Internal MCLv3 sendto function. + * Assumes the caller is already locked. + * Uses the same parameters and return value as mcl_sendto(). + */ +extern int mcl_sendto2 (class mcl_cb *const mclcb, + const void *data, + int len, + const struct sockaddr *saddr, + int saddr_len); +#endif + +/** + * Internal MCLv3 sendmsg function. + * Assumes the caller is already locked. + * Uses the same parameters and return value as mcl_sendmsg(). + */ +extern INT64 mcl_sendmsg2 (class mcl_cb *const mclcb, + struct mcl_msghdr *msg, + mcl_msgflag flags); + + diff --git a/src/alc/mcl_lib_api_alc.h b/src/alc/mcl_lib_api_alc.h new file mode 100644 index 0000000..8bdf59d --- /dev/null +++ b/src/alc/mcl_lib_api_alc.h @@ -0,0 +1,366 @@ +/* $Id: mcl_lib_api_alc.h,v 1.38 2005/05/23 14:35:53 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_LIB_API_ALC_H /* { */ +#define MCL_LIB_API_ALC_H + +/* + * MCL API definition, part II: the reliable multicast specific part of + * the MCL API. + * + * WARNING: This file must not be included by an application, only file: + * src/common/mcl_lib_api.h + * must be included! + */ + +enum mcl_tx_profile { + MCL_TX_PROFILE_LOW_RATE_INTERNET = 0, /* modem connection */ + MCL_TX_PROFILE_MID_RATE_INTERNET, /* eg with VPNs, xDSL */ + MCL_TX_PROFILE_HIGH_SPEED_INTERNET, /* several Mbps connection */ + MCL_TX_PROFILE_HIGH_SPEED_LAN, /* fast/Gbps ethernet LAN */ +}; + + +/** + * List of events available for mcl_wait_event(). + */ +#define MCL_WAIT_EVENT_END_TX 0 +#define MCL_WAIT_EVENT_END_RX 1 +#define MCL_WAIT_EVENT_CLOSED 2 + + +/** + * FEC schemes available. + * Use one of them for mcl_ctl(SET_FEC_CODE). + * A FEC scheme defines both the FEC codec and the way it is used, + * i.e. the {FEC Encoding ID; FEC Instance ID} tuple. + */ +enum mcl_fec_scheme { + MCL_FEC_SCHEME_NULL = 0, /* NULL code (i.e. no FEC encoding) */ + MCL_FEC_SCHEME_RSE_129_0, + /* Reed-Solomon erasure FEC code */ + MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0, + /* Low Density Generator Matrix-STAIRCASE */ + MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1 + /* Low Density Generator Matrix-TRIANGLE */ +}; +#define MCL_FEC_SCHEME_NB 4 /* Number of FEC schemes available */ + + +/** + * Possible congestion controls protocols. + */ +enum mcl_congestion_control_scheme { + INVALID_CC = 0, /* initial value, nothing choosen */ + NO_CC, /* choose not to have any CC */ + RLC_CC, /* choose to have RLC CC */ + FLID_SL_CC /* choose to have FLID SL (static layer) CC */ +}; + + +/** + * ADU reception status. + */ +/** possible values of the adu->rx_status field. */ +enum mcl_adu_rx_status { + ADU_STATUS_NIL = 0, /* void status */ + ADU_STATUS_IN_PROGRESS, /* not yet ready */ + ADU_STATUS_COMPLETED, /* received enough DUs for all blocks */ + ADU_STATUS_DECODED, /* COMPLETED and FEC decoding done */ + ADU_STATUS_DELIVERED /* sent to the receiving application */ +}; + + +/** structure used by the MCL_OPT_GET_ADU_RX_INFO option. */ +typedef struct mcl_adu_rx_info { + UINT64 toi; /* Transport Objet Identifier of the ADU */ + UINT64 len; /* ADU length */ + UINT64 recvd_src_data; /* number of bytes received or decoded. */ + /* Does not include parity symbols. */ + enum mcl_adu_rx_status rx_status; /* rx status: completed,delivered...*/ +} mcl_adu_rx_info_t; + + +/** + * structure used to communicate FTI information from outside + * mcl to the lib, used by the MCL_OPT_SET_FTI_INFO option. + */ +typedef struct FTI_infos { + UINT64 toi; /* Transport Objet Identifier of the ADU */ + UINT32 fec_encoding_id;/* FEC encoding ID (RFC3452) */ + UINT16 fec_instance_id;/* FEC instance ID (RFC3452) */ + UINT32 fec_key; /* LDGM/LDPC specific: random seed */ + UINT64 adu_len; /* ADU length in bytes */ + UINT32 max_k; /* max src blk len in nb of symbols */ + UINT32 max_n; /* max enc blk len in nb of symbols */ + UINT16 symbol_len; /* full-sized symbol length in bytes */ +} FTI_infos_t; + + + +/* + * library options set with the mcl_ctl() function + */ +enum mcl_opt { + /**********************************************************************/ + /* + * common options used by both sender and receiver + */ + MCL_OPT_LAYER_NB = 1, /* number of transmission layers at a sender, */ + /* and maximum number of layer at a receiver. */ + /* if more than 1 is specified, the actual */ + /* number of layers at a receiver will be */ + /* determined by the congestion control */ + /* protocol dynamically. */ + /* argument: int */ + MCL_OPT_PORT, /* port number (uni or multicast), HOST order */ + /* argument: int (and not UINT16!) */ + MCL_OPT_ADDR, /* IPv4 address (uni or multicast), HOST order*/ + /* DEPRECATED, use BIND */ + /* argument: int */ + MCL_OPT_BIND, /* specify sockaddr struct, NETWORK byte order*/ + /* argument: sockaddr_in or sockaddr_in6 */ + MCL_OPT_TTL, /* specify TTL (time to live) in [0;127] range*/ + /* argument: int */ + MCL_OPT_DEMUX_LABEL, /* specify the LCT demultiplexing label, TSI */ + /* (Transport Session Idf) */ + /* argument: int */ + MCL_OPT_STATS, /* collect various stats */ + /* argument: int */ + MCL_OPT_VERBOSITY, /* verbosity level */ + /* argument: int */ + MCL_OPT_DEBUG, /* no tx/rx thread to simplify debug */ + /* argument: none */ + MCL_OPT_MOREABOUT, /* version # and credits */ + /* argument: none */ + MCL_OPT_TMP_DIR, /* put temporary files in this directory */ + /* argument: a `\0' terminated string, size */ /* given */ +#define DEL_MODE_PUSH 0 /* tx once, assumes synchronized rx */ +#define DEL_MODE_ON_DEMAND 1 /* tx cyclically, rx start at any time*/ +#define DEL_MODE_STREAMING 2 /* streaming mode */ + MCL_OPT_DELIVERY_MODE, /* specify the delivery mode: push/on-demand */ + /* (cf. i-draft) argument: int */ + /* two multicast specific socket options - rarely required... */ + // MCL_OPT_NETIF is now DEPRECATED !!! */ + MCL_OPT_SET_NETIF_ADDR, /* specify the network interface address to */ + /* be used, NETWORK byte order. */ + /* argument: sockaddr_in or sockaddr_in6 */ + MCL_OPT_SET_NETIF_NAME, /* specify the network interface name to */ + /* be used. */ + /* argument: string (e.g. "eth0"). The optlen */ + /* must contain the string len given by strlen*/ + MCL_OPT_LOOPBACK, /* will we send mcast packet to local apps */ + /* argument: int passed to setsockopt as is */ + + /* + * FLUTE specific common options + */ + MCL_OPT_SET_FLUTE_MODE, /* Set the FLUTE mode (false by default). */ + /* no argument */ + /* + * METAOBJECT specific common options + */ + MCL_OPT_SET_META_OBJECT_ONLY_MODE, /* Set the meta_object only mode */ + /* i.e. all objects sent or received are */ + /* metaobjects (default: false). */ + /* no argument */ + + /**********************************************************************/ + /* + * options used by the sender + */ + MCL_OPT_SET_NEXT_TOI, /* set the Transport Object Id (AKA ADU id) */ + /* to use for the next object submitted */ + /* argument: UINT32 */ + MCL_OPT_SET_NEXT_ADU_HIGH_IMPORTANCE, /* next ADU is of high */ + /* priority (e.g. control data, FDT...) */ + /* Must be called before each high prio obj. */ + /* no argument */ + MCL_OPT_FLUSH_HIGH_IMPORTANCE_OBJECTS, /* send all high prio objects */ + /* immediatly. */ + /* The high prio objects will continue to be */ + /* sent after the flush, but at normal high */ + /* priority rate */ + /* no argument */ + MCL_OPT_TX_PROFILE, /* select a pre-defined transmission profile */ + /* argument: int (see mcl_tx_profile enum) */ + MCL_OPT_PRINT_TX_PROFILE,/* print the transmission profile */ + /* argument: none */ + MCL_OPT_DATAGRAM_SIZE, /* datagram size */ + /* argument: int */ + MCL_OPT_TX_RATE, /* tx rate in full-size packets/s on base */ + /* layer */ + /* argument: double */ + MCL_OPT_SET_CC_SCHEME, /* specify the congestion control mode */ + /* argument: mcl_congestion_control_scheme */ + MCL_OPT_FEC_RATIO, /* set the FEC packets ratio (n/k) (e.g. 2.0 */ + /* adds 100% of fec pkts, 3.0 adds 200% fec) */ + /* argument: float (must be >= 1.0) */ + MCL_OPT_NB_OF_TX, /* send DUs that number of times on base layer*/ + /* argument: int (default 1 or infinity if */ + /* in DEL_MODE_ON_DEMAND mode) */ + MCL_OPT_ADD_NB_OF_TX, /* extends the number of times a DU is sent */ + /* on base layer to this number of cycles. */ + /* argument: int */ + MCL_OPT_REUSE_APPLI_TX_BUFFER, /* can MCL take control of appli buffer*/ + /* used to avoid an extra copy within MCL */ + /* Warning: buf must be alloc by c/re/malloc */ + /* argument: int (0 (default) or 1) */ + MCL_OPT_VIRTUAL_TX_MEMORY, /* do you need the virtual tx mem service? */ + /* argmument: int (0 or 1 (default)) */ + MCL_OPT_VIRTUAL_RX_MEMORY, /* do you need the virtual rx mem service? */ + /* argmument: int (0 or 1 (default)) */ + MCL_OPT_KEEP_DATA, /* step1: wait before doing ADU scheduling */ + /* no argument */ + MCL_OPT_PUSH_DATA, /* step2: now perform ADU scheduling and send */ + /* no argument */ + MCL_OPT_KEEP_META_OBJECT,/* step1: start of a new meta object */ + /* no argument */ + MCL_OPT_PUSH_META_OBJECT,/* step2: end of current meta object*/ + /* no argument */ + MCL_OPT_RESET_TRANSMISSIONS, /* delete and free all transmission */ + /* tables and the associated ADUs */ + /* WARNING: this control deletes ALL ADUs */ + /* that are in the transmission table, so take*/ + /* care if you use anticipated_tx_for_push */ + /* since it will also delete anticipated ADUs.*/ + /* no argument */ + MCL_OPT_STOP_TRANSMITTING_ADU, /* removes the specified ADU from the */ + /* transmission tables, and frees the ADU */ + /* argument: UINT64, TOI of the ADU */ +#ifdef SVSOA_RECV + MCL_OPT_SET_RX_LEVEL, /* set the reception level at session start*/ + /* argument: int (number of layers)*/ + MCL_OPT_GET_RX_LEVEL, /* return reception level*/ + /* argument: int, contains the value on return*/ + MCL_USED_FOR_BASE_VIDEO_LAYER,/* this session is used for base video */ + /* layer. argument: none */ +#endif + +#define MCL_SCHED_LCT1 0 /* see mcl_profile.h for descr. */ +#define MCL_SCHED_NB 1 /* nb of schedulers defined */ + MCL_OPT_SCHED, /* choose a scheduler from above possibilities*/ + /* argument: int */ +#define MCL_SCHED_SEQUENTIAL_OBJ_ORDER 0 /* tx ADUs in sequence */ +#define MCL_SCHED_RANDOM_OBJ_ORDER 1 /* tx ADUs in random order in each */ + /* layer */ +#define MCL_SCHED_PARTIALLY_MIXED_ORDER 2 /* mix partially all DUs of all ADUs*/ +#define MCL_SCHED_MIXED_ORDER 3 /* mix all DUs of all ADUs */ + MCL_OPT_OBJ_SCHED, /* choose an object scheduler */ + /* argument: int */ + MCL_OPT_SET_FEC_CODE, /* set the FEC codec to be used. If not */ + /* available, an error is returned */ + /* argument: int */ + MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC, /* retrieve the maximum */ + /* block size in bytes for current FEC code */ + /* argument: int, contains the value on return*/ + + /**********************************************************************/ + /* + * options used by the receiver + */ + MCL_OPT_SET_SSM, /* set the SSM (Source Specific Multicast) */ + /* mode at the receiver. In that case, the */ + /* MCL_OPT_SRC_ADDR is mandatory */ + /* argument: int (0 (default) or 1) */ + MCL_OPT_SRC_ADDR, /* (unicast) source address, HOST order, only */ + /* needed at a receiver. */ + /* argument: sockaddr_in or sockaddr_in6 */ + MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, /* boolean specifying if ADU can */ + /* be delivered in arrival order or not */ + /* (i.e. in sequence). */ + /* Compatible with FLUTE delivery) */ + /* argument: int (0 (default) or 1) */ + MCL_OPT_POSTPONE_FEC_DECODING, /* boolean: is FEC decoding postponed? */ + /* only valid with RSE, doesn't apply to LDPC */ + /* argument: int, 0 or 1 (default, postponed) */ + MCL_OPT_NEVER_LEAVE_BASE_LAYER, /* mcl_wait(MCL_WAIT_EVENT_CLOSED) */ + /* needs it; argument: int (0 (default) or 1) */ + MCL_OPT_GET_ADU_RX_INFO, /* Get reception information for this ADU. */ + /* argument: pointer to mcl_adu_rx_info_t */ + MCL_OPT_SET_FTI_INFO, /* Set the FTI information */ + /* argument: pointer to FTI_infos_t */ + + /* + * FLUTE specific options at a receiver + */ + MCL_OPT_SET_FLUTE_STORE_ALL_ADUS_BY_DEFAULT, + /* If set, all received ADUs will be stored */ + /* in MCL, no matter whether or not they have */ + /* been requested by FLUTE. When set, this */ + /* mode improves delivery efficiency, since */ + /* it is not required to wait for a */ + /* DELIVER_THIS_ADU_TO_APPLI to start ADU rx. */ + /* WARNING: if set and if an FDT Entry has */ + /* been missed the ADU will remain in the MCL */ + /* lib till the session closes! */ + /* Requires that SET_FLUTE_MODE has been */ + /* issued previously. */ + /* argument: int (0 (default) or 1) */ + MCL_OPT_FLUTE_DELIVER_THIS_ADU_TO_APPLI, + /* Specifies a TOI (AKA. ADU Id) to deliver. */ + /* TOIs (!=0) that have not been enabled with */ + /* a FLUTE_DELIVER_THIS_ADU_TO_APPLI won't be */ + /* delivered to FLUTE. */ + /* Requires that SET_FLUTE_MODE has been */ + /* issued previously. */ + /* argument: int (TOI of the desired ADU) */ + + /**********************************************************************/ + /* + * options used by rlc_ctl() for RLC congestion control init + * (rarely required... use default values) + */ + RLC_OPT_SP_CYCLE, /* interval between 2 SPs at layer 0 */ + /* (in microseconds) */ + /* argument: int */ + RLC_OPT_PKT_TIMEOUT, /* Time To Wait for a late packet to arrive */ + /* before assuming it's lost */ + /* argument: int */ + RLC_OPT_DEAF_PERIOD, /* Deaf period after dropping a layer */ + /* argument: int */ + RLC_OPT_LATE_ACCEPTED, /* number of late packets accepted between */ + /* 2 SPs at highest layer */ + /* argument: int */ + RLC_OPT_LOSS_ACCEPTED, /* number of lost packets accepted between */ + /* 2 SPs at highest layer */ + /* argument: int */ + RLC_OPT_LOSS_LIMIT, /* loss limit before layer drop */ + /* argument: int */ + RLC_OPT_LOSS_TIMEOUT, /* timeout for loss limit */ + /* argument: int */ + RLC_OPT_AGGRESSIVE_CC, /* boolean: 1 for an aggressive RLC profile, */ + /* more tolerant to packet losses than default*/ + /* argument: int (0 or 1) */ + + /**********************************************************************/ + /* + * options used by FLIDs_ctl() for FLID-SL congestion control init + * (rarely required... use default values) + */ + FLIDS_OPT_TSD, /* TimeSlot Duration (in microseconds) */ + /* argument: int */ + + FLIDS_OPT_DEAF_PERIOD /* Duration of Deaf period in multiple of TSD */ + /* argument: int */ +}; + +#endif /* } MCL_LIB_API_ALC */ diff --git a/src/alc/mcl_meta_object.cpp b/src/alc/mcl_meta_object.cpp new file mode 100644 index 0000000..4741ddc --- /dev/null +++ b/src/alc/mcl_meta_object.cpp @@ -0,0 +1,640 @@ +/* $Id: mcl_meta_object.cpp,v 1.28 2005/01/11 15:40:16 moi Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + +#ifdef METAOBJECT_USED + + +/****************************************************************************** + * mcl_meta_object Constructor, at a sender. + */ +mcl_meta_object::mcl_meta_object (class mcl_cb* mclcb) +{ + this->moid = 0; + this->nb_obj = 0; + this->data = NULL; + this->len = 0; + this->object_list_head = NULL; + this->object_list_tail = NULL; + this->mclcb = mclcb; + this->findobject_cache = NULL; + this->nb_delivered_obj = 0; +} + +/****************************************************************************** + * mcl_meta_object Constructor, at a receiver. + */ +mcl_meta_object::mcl_meta_object (char* odt, int odt_len, class mcl_cb* mclcb) +{ + + UINT32 moid_length; + UINT32 nb_obj_len; + UINT32 obj_len_len; + + this->moid = 0; + this->nb_obj = 0; + this->data = NULL; + this->len = 0; + this->object_list_head = NULL; + this->object_list_tail = NULL; + this->mclcb = mclcb; + this->findobject_cache = NULL; + this->nb_delivered_obj = 0; + + /* get the length of moid */ + moid_length = ((*(UINT32*)odt >> 24) & 0x0000000F); + if (moid_length != 2) + PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::add_object_description_table: ERROR, MOI size != 32bits not supported\n")) + + /* get the length of nb of objects */ + nb_obj_len = ((*(UINT32*)odt >> 20) & 0x0000000F); + if (nb_obj_len != 2) + PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::add_object_description_table: ERROR, nb_obj_len size != 32bits not supported\n")) + + /* get the length of object length */ + obj_len_len = ((*(UINT32*)odt >> 16) & 0x0000000F); + if (obj_len_len != 4) + PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::add_object_description_table: ERROR, obj_len_len size != 32bits not supported\n")) + + /* get the moid of the description table */ + moid = *(UINT32*)((char*)odt + 4); + + /* the number of objects in meta object */ + nb_obj = *(UINT32*)((char*)odt + 8); + + + /* get the length of the objects out of the descritption table + * and fill the object list */ + for(unsigned int i=0; inext = (object*) malloc(sizeof(struct object)); + object_list_tail = object_list_tail->next; + } + + memcpy(&object_list_tail->len, (char*)odt + 12 + i*obj_len_len, obj_len_len); + object_list_tail->delivered = false; + object_list_tail->first_blk = NULL; + object_list_tail->first_blk_position = 0; + object_list_tail->last_decoded_du = NULL; + object_list_tail->last_decoded_du_offset = 0; + object_list_tail->first_du = NULL; + object_list_tail->next=NULL; + + } + + this->mclcb = mclcb; +} + +/****************************************************************************** + * mcl_meta_object Destructor. + */ +mcl_meta_object::~mcl_meta_object () +{ + struct object *temp; + + free(this->data); + this->data = NULL; + + while(object_list_head!=NULL) + { + temp = object_list_head; + object_list_head = object_list_head->next; + free(temp); + } + object_list_tail = NULL; + findobject_cache = NULL; + mclcb = NULL; +} + +/****************************************************************************** + * get_id : returns the MO id. + * => See header file for more informations. + */ +UINT32 mcl_meta_object::get_id() +{ + return this->moid; +} + + +/****************************************************************************** + * set_id : sets the MO id. + * => See header file for more informations. + */ +void mcl_meta_object::set_id(UINT32 moid) +{ + this->moid = moid; +} + +/****************************************************************************** + * add_object : adds an object to the MO. + * => See header file for more informations. + */ +int mcl_meta_object::add_object(struct mcl_msghdr *msg) +{ + struct mcl_iovec *iov; /* iovec */ + INT32 fd; /* input data file (if applicable) */ + + TRACELVL(5, (mcl_stdout, "-> mcl_meta_object::add_object\n")) + + iov = msg->msg_iov; + + if (!mclcb->is_a_sender()) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object::add_object: function can only be used at sender side")); + } + + if ((float) iov->iov_len > pow((float) 2,(float) ((OBJECTS_LEN_LEN*8)-1))) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object::add_object: object size is too important (max 2^(32-1))")); + return -1; + } + + int padding_len = 0; /* length of in bytes padding at the end of the object */ + + /* add new object in the list of objects */ + if (object_list_tail == NULL) + { + object_list_tail = object_list_head = (object*) calloc(1, sizeof(struct object)); + } + else + { + object_list_tail->next = (object*) calloc(1, sizeof(struct object)); + object_list_tail = object_list_tail->next; + } + + object_list_tail->len = iov->iov_len; + object_list_tail->delivered = false; + object_list_tail->next=NULL; + + /* calculate padding length */ + if (iov->iov_len % mclcb->get_payload_size()!=0) padding_len = mclcb->get_payload_size() - (iov->iov_len % mclcb->get_payload_size()); + ASSERT((iov->iov_len + padding_len) % mclcb->get_payload_size() == 0) + + if (this->data == NULL) + { + if (!(this->data = (char*) calloc(1, this->len + iov->iov_len + padding_len))) { + PRINT_ERR((mcl_stderr, "mcl_meta_object::add_object: Error: Cannot alloc memory!\n")) + } + } + else + { + if (!(this->data = (char*) realloc(this->data, this->len + iov->iov_len + padding_len))) { + PRINT_ERR((mcl_stderr, "mcl_meta_object::add_object: Error: Cannot realloc memory!\n")) + } + } + + + /* get the object data and copy it into the metaobject buffer */ + if (iov->iov_type == MCL_IOV_TYPE_BUFFER) { + /* copy data to meta object data */ + memcpy(this->data + this->len, iov->iov_base, iov->iov_len); + } else { + if (iov->iov_filename == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_meta_object::add_object: ERROR, NULL iov_filename\n")) + return MCL_ERROR; + } + fd = mcl_file_open(iov->iov_filename, O_RDONLY, 0); + if (fd < 0) { + PRINT_ERR((mcl_stderr, + "mcl_meta_object::add_object: ERROR, mcl_file_open() failed for iov_filename \"%s\"\n", + iov->iov_filename)) + return MCL_ERROR; + } + if (mcl_file_lseek(fd, iov->iov_offset) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_meta_object::add_object: ERROR, mcl_file_lseek() failed\n")) + return MCL_ERROR; + } + if (mcl_file_read(fd, this->data, iov->iov_len) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_meta_object::add_object: ERROR, mcl_file_read() failed\n")) + return MCL_ERROR; + } + } + + + /* add padding */ + memset(this->data + this->len + iov->iov_len, 0, padding_len); + /* new meta object length */ + this->len = this->len + iov->iov_len + padding_len; + + nb_obj++; + + TRACELVL(5, (mcl_stdout, "<- mcl_meta_object::add_object\n")) + + return 0; +} + + + +/****************************************************************************** + * get_object_description_table : get the ODT of the MO. + * The MODT looks like this: + * + * 0 1 2 3 + * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | VER | ID_LEN|NBOBLEN|OBLENLEN| PADDING | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | MOID | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | Number of objects | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | length of object 0 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | length of object 1 | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | . | + * | . | + * | . | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * | length of object n (n = number of objects - 1) | + * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + * + * => See header file for more informations. + */ +void mcl_meta_object::get_object_description_table(char** odt_data, int *odt_len) +{ + UINT32 word1 = 0; + struct object *temp; + int i = 0; + + TRACELVL(5, (mcl_stdout, "-> mcl_meta_object::get_object_description_table\n")) + + if (!mclcb->is_a_sender()) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object::get_object_description_table: function can only be used at sender side")); + } + + if (this->moid == 0) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object::get_object_description_table: moid has not been set")); + } + + if (MOID_LEN != 2) + PRINT_ERR((mcl_stderr, "mcl_meta_object::get_object_description_table: ERROR, MOI size != 32bits not supported\n")) + if (NB_OF_OBJECTS_LEN != 2) + PRINT_ERR((mcl_stderr, "mcl_meta_object::get_object_description_table: ERROR, nb_of_objects size != 32bits not supported\n")) + if (OBJECTS_LEN_LEN != 4) + PRINT_ERR((mcl_stderr, "mcl_meta_object::get_object_description_table: ERROR, object_size size != 32bits not supported\n")) + + /* calculate the length of the ODT that will be created */ + *odt_len = 4 + MOID_LEN*2 + NB_OF_OBJECTS_LEN*2 + nb_obj*OBJECTS_LEN_LEN; + + /* allocate memory for the ODT */ + if (!(*odt_data = (char*) calloc(1, *odt_len))) { + PRINT_ERR((mcl_stderr, "mcl_meta_object::get_object_description_table: Error: Cannot malloc memory!\n")) + } + + /* create first word of the ODT */ + word1 = (ODT_VERSION << 28) | ((MOID_LEN & 0x0000000F) << 24) | ((NB_OF_OBJECTS_LEN & 0x0000000F) << 20) | ((OBJECTS_LEN_LEN & 0x0000000F) << 16); + memcpy((void*) *odt_data, &word1, 4); + /* copy moid */ + memcpy((void *)(((char*)(*odt_data)) + 4), &this->moid, MOID_LEN*2); + /* copy nb_of_objects */ + memcpy((void *)((int)*odt_data + 4 + MOID_LEN*2), &nb_obj, NB_OF_OBJECTS_LEN*2); + /* copy all object lengths */ + temp = object_list_head; + while(temp!=NULL) + { + memcpy((void *)((int)*odt_data + 4 + MOID_LEN*2 + NB_OF_OBJECTS_LEN*2 + i * OBJECTS_LEN_LEN), &temp->len, OBJECTS_LEN_LEN); + temp = temp->next; + i++; + } + + TRACELVL(5, (mcl_stdout, "<- mcl_meta_object::get_object_description_table\n")) + +} + +/****************************************************************************** + * get_meta_object_data : get the data of the MO. + * => See header file for more informations. + */ +void mcl_meta_object::get_meta_object_data(char** metaobj_data, int *metaobj_len) +{ + + TRACELVL(5, (mcl_stdout, "-> mcl_meta_object::get_meta_object_data\n")) + + if (!mclcb->is_a_sender()) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object::get_meta_object_data: function can only be used at sender side")); + } + + *metaobj_data = this->data; + *metaobj_len = this->len; + + TRACELVL(5, (mcl_stdout, "<- mcl_meta_object::get_meta_object_data\n")) +} + + + +/****************************************************************************** + * check_for_decoded_objects : check if objects have been decoded. + * => See header file for more informations. + */ +int mcl_meta_object::check_for_decoded_objects(struct mcl_msghdr *msg, enum mcl_msgflag flags) +{ + char *userbuf; /* user buffer */ + UINT32 userlen; /* user buffer length */ + adu_t *adu; /* adu that corresponds to the meta + object */ + block_t *blk; + du_t *du; + UINT32 obj_position = 0;/* position (offset) of the current + object in the meta object */ + struct object * temp; + char *dst; /* where to do data copy in userbuf */ + + /* needed for optimitzations */ + UINT32 last_blk_position = 0; + block_t *last_blk = NULL; + + TRACELVL(5, (mcl_stdout, "-> mcl_meta_object::check_for_decoded_objects\n")) + + ASSERT(mclcb->is_a_receiver()); + + /* search the adu that corresponds to the meta object */ + if ((adu = mclcb->rx_window.find_adu(mclcb, this->moid, -1)) == NULL) + return 0; + + + /* check if we finished delivering the MO */ + if (this->nb_delivered_obj == this->nb_obj) + { + /* All objects have been delivered */ + /* the adu can now be freed*/ + mcl_rx_free_this_adu(mclcb, adu); + + /* return code in order to free MO-instance */ + return -1; + } + + /* + * then check for objects that have not been delivered before... + */ + last_blk = adu->block_head; + if (this->findobject_cache != NULL) + { + /* get pointer to the object that was last decoded by previous + * MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT, or first + * object list that could not be decoded. */ + + temp = object_list_head; + while (temp != NULL && temp != this->findobject_cache) + { + if ((temp->len % mclcb->get_payload_size()) == 0) obj_position += temp->len; + else obj_position += temp->len + mclcb->get_payload_size() - (temp->len % mclcb->get_payload_size()); + temp = temp->next; + } + + this->findobject_cache = NULL; + } + else + temp = object_list_head; + + /* go through list of objects */ + while (temp != NULL) + { + bool object_ready = false; + + if (!temp->delivered) + { + if (msg != NULL && !(flags == MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT) && msg->msg_iov->iov_len < (int) temp->len) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object::check_for_decoded_objects: user buffer too small (user_buffer %i, data_size %i)!!!\n", msg->msg_iov->iov_len, temp->len)) + exit(0); + } + + /* + * not already delivered: check if we can deliver it... + */ + + /* find the right block first */ + UINT32 blk_position; + + if (temp->first_blk != NULL) + { + blk = temp->first_blk; + blk_position = temp->first_blk_position; + } + else + { + blk_position = last_blk_position; + + for (blk = last_blk; (unsigned int) blk->seq < adu->blocking_struct.block_nb; blk++) + { + if (!blk) break; + if (blk_position + blk->len > obj_position) break; + blk_position += blk->len; + } + + temp->first_blk = blk; + temp->first_blk_position = blk_position; + } + + last_blk = blk; + last_blk_position = blk_position; + + /* we have found the right block... now check the du's */ + + if (blk != NULL && blk->du_head != NULL) + { + + UINT32 obj_len_decoded = 0; + + /* find the right du then */ + if (temp->last_decoded_du != NULL || temp->first_du != NULL) + { + if (temp->first_du != NULL) du = temp->first_du; + else + { + obj_len_decoded = temp->last_decoded_du_offset; + du = temp->last_decoded_du; + blk = du->block; + } + } + else + { + + UINT32 i; + /* use rint to compensate rounding errors */ + /* floor or ceil should can not be used */ + UINT32 first_du_of_obj = (UINT32) rint((double) (obj_position - blk_position) / mclcb->get_payload_size()); + for(du = blk->du_head, i = 0; i < first_du_of_obj && first_du_of_obj!=du->seq;du=du->next, i++){} + if (first_du_of_obj==du->seq) temp->first_du = du; + else + { + /* we did not received the first du of this object + * jump to the next object */ + goto check_next_object; + } + } + + while((temp->first_du == du) || (du->seq == du->prev->seq + 1 && du != blk->du_head) || (du == blk->du_head && du->seq == 0)) + { + if (!du) goto check_next_object; + if (du->data) + { + obj_len_decoded += du->len; + if (obj_len_decoded >= temp->len) + { + /* object decoded !!! */ + object_ready = true; + break; + } + } + else goto check_next_object; + + if (blk->du_head == du->next) + { + if (du->seq != blk->k - 1) + { + /* this is not the last du of the block */ + goto check_next_object; + } + /* next du is on next block */ + blk++; + temp->last_decoded_du_offset = obj_len_decoded; + temp->last_decoded_du = du; + if ((du = blk->du_head) == NULL) goto check_next_object; + } + else + { + temp->last_decoded_du_offset = obj_len_decoded; + temp->last_decoded_du = du; + du=du->next; + } + } + + + if (object_ready) + { + /* The object is ready, and data can be delivered to appli. + * We now copy the data if requested by appli */ + + if (msg == NULL || (flags == MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT)) + { + this->findobject_cache = temp; + + if (msg == NULL || flags == MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT) + { + /* it was just to check if an object was available... */ + return temp->len; + } + } + + userbuf = (char *) msg->msg_iov->iov_base; + userlen = msg->msg_iov->iov_len; + + obj_len_decoded = 0; + dst = userbuf; + + blk = temp->first_blk; + du = temp->first_du; + + while ((temp->first_du == du) || (du->seq == du->prev->seq + 1 && du != blk->du_head) || (du == blk->du_head && du->seq == 0)) + { + obj_len_decoded += du->len; + if (obj_len_decoded >= temp->len) + { + /* do not copy the padding bits */ + if (obj_len_decoded > temp->len) + { + memcpy(dst, du->data,(int) (temp->len % mclcb->get_payload_size())); + dst += temp->len % mclcb->get_payload_size(); + obj_len_decoded = obj_len_decoded - du->len + (temp->len % mclcb->get_payload_size()); + } + else + { + memcpy(dst, du->data, (int) du->len); + dst += du->len; + } + break; + } + else + { + memcpy(dst, du->data,(int) du->len); + dst += du->len; + } + + if (blk->du_head == du->next) + { + if (du->seq != blk->k - 1) + { + /* this is not the last du of the block */ + goto check_next_object; + } + /* next du is on next block */ + blk++; + if ((du = blk->du_head) == NULL) goto check_next_object; + } + else du = du->next; + + } + if (flags == MCL_MSG_DEFAULT) + { + temp->delivered = true; + this->nb_delivered_obj++; + } + ASSERT(obj_len_decoded == temp->len) + TRACELVL(5, (mcl_stdout, "<- mcl_meta_object::check_for_decoded_objects: object of size %i returned\n", temp->len)) + return temp->len; + } + } + } + +check_next_object: + if (!temp->delivered && this->findobject_cache == NULL) + { + /* Remember first non decoded object for optimization */ + this->findobject_cache = temp; + } + + if (mclcb->rx_window.uses_ordered_delivery_to_appli() && !temp->delivered) + { + /* Ordered delivery is requested, but the next object to deliver + * is not ready yet. */ + TRACELVL(5, (mcl_stdout, "<- mcl_meta_object::check_for_decoded_objects: no object returned\n")) + return 0; + } + + + /* Move to next object in list, and update obj_position, + * in order to be able to locate next object */ + if ((temp->len % mclcb->get_payload_size()) == 0) obj_position += temp->len; + else obj_position += temp->len + mclcb->get_payload_size() - (temp->len % mclcb->get_payload_size()); + temp = temp->next; + } + + TRACELVL(5, (mcl_stdout, "<- mcl_meta_object::check_for_decoded_objects: no object returned\n")) + + return 0; +} + +#endif /* METAOBJECT_USED */ diff --git a/src/alc/mcl_meta_object.h b/src/alc/mcl_meta_object.h new file mode 100644 index 0000000..c3acca3 --- /dev/null +++ b/src/alc/mcl_meta_object.h @@ -0,0 +1,149 @@ +/* $Id: mcl_meta_object.h,v 1.12 2005/01/11 15:40:16 moi Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_METAOBJ_LAYER /* { */ +#define MCL_METAOBJ_LAYER + +typedef struct object { + UINT32 len; /* number of bytes in this object + * (not padded) */ + struct object *next; /* next object of the same meta object + * in list */ + block_t *first_blk; /* first block of this object */ + int first_blk_position; /* offset of this first block (in bytes) */ + du_t *first_du; /* first du of this object */ + du_t *last_decoded_du; /* last decoded du of this object */ + int last_decoded_du_offset; /* offset of this last du (in bytes) */ + bool delivered; /* at sender side: true if the object + * has already been delivered to the + * application */ +} object_t; + + +class mcl_meta_object{ + +public: + + /****** Public Members ************************************************/ + /** + * Constructor at a sender. + * @param mclcb (IN) mclcb. + */ + mcl_meta_object (class mcl_cb * mclcb); + + /** + * Constructor at a receiver. + * The object description table is passed as a parameter. + * @param odt (IN) pointer to the ODT of the MO. + * @param odt_len (IN) length of the ODT. + * @param mclcb (IN) mclcb. + */ + mcl_meta_object (char* odt, int odt_len, class mcl_cb * mclcb); + + /** Destructor */ + ~mcl_meta_object (); + + /** + * Returns the meta object session id. + * The session identifier is set once, at session creation (at a receiver), + * and through set_id at a sender. + * @return session id + */ + UINT32 get_id(); + + /** + * Sets the meta object session id. + * The session identifier is set once, at session creation (at a receiver), + * and through set_id at a sender. + * @param session id + */ + void set_id(UINT32 moid); + + + /** + * Adds a new object to the MO. All objects of an MO are + * added to the MO by using this function. Is usually called after + * a mcl_meta_object (char* odt, int odt_len, class mcl_cb * mclcb). + * Only at sender side. + * @param msg (IN) Message control structure describing the object + * @return <0 if error. + */ + int add_object (struct mcl_msghdr *msg); + + /** + * Creates and returns the ODT of the MO. + * Only at sender side. + * @param obj_data (OUT) pointer to the buffer allocated for the ODT. + * @param obj_data (IN-OUT) pointer to integer containing the length of the ODT. + */ + void get_object_description_table (char** odt_data, int *odt_len); + + /** + * Returns the data of the MO. + * Only at sender side. + * @param metaobj_data (OUT) pointer to the buffer allocated for the MO. + * @param metaobj_len (IN-OUT) pointer to integer containing the length of the MO. + */ + void get_meta_object_data (char** metaobj_data, int *metaobj_len); + + /** + * This function checks if objects of the MO have been decoded. + * It returns the length of the object and 0 if no object is available. + * Returns -1 if all objects have already been delivered (MO can be deleted + * in this case). + * Only at receiver side + * @param msg pointer to the mcl_msghdr structure. + * @param flags flags to control some specific features. + * @return number of bytes received (or available if + * MCL_MSG_GET_SIZE_OF_AVAILABLE_OBJECT or MCL_PEEK is used), + * 0 if no objects are ready, -1 if all objects have already + * been delivered. + */ + int check_for_decoded_objects (struct mcl_msghdr *msg, enum mcl_msgflag flags); + + + /****** Public Attributes ********************************************/ + /** number of objects in this metaobject. */ + UINT32 nb_obj; + +private: + /****** Private Attributes ********************************************/ + /** id of this meta_object. */ + UINT32 moid; + /** pointer to head of list of objects included in the meta object. */ + struct object *object_list_head; + /** pointer to tail of list of objects included in the meta object. */ + struct object *object_list_tail; + /** number of objects delivered (sender side) in this metaobject. */ + UINT32 nb_delivered_obj; + + /** ptr to data buffer. */ + char *data; + /** length of data buffer. */ + int len; + /** pointer to the object that has been returned by MCL_MSG_GET_SIZE_OF_AVAILABLE_OBJECT + * or MCL_MSG_PEEK. */ + struct object *findobject_cache; + + class mcl_cb* mclcb; +}; + +#endif diff --git a/src/alc/mcl_meta_object_layer.cpp b/src/alc/mcl_meta_object_layer.cpp new file mode 100644 index 0000000..e241ee0 --- /dev/null +++ b/src/alc/mcl_meta_object_layer.cpp @@ -0,0 +1,351 @@ +/* $Id: mcl_meta_object_layer.cpp,v 1.20 2005/01/11 15:40:16 moi Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + +#ifdef METAOBJECT_USED + +/****************************************************************************** + * mcl_meta_object_layer Constructor. + */ +mcl_meta_object_layer::mcl_meta_object_layer(class mcl_cb* mclcb) +{ + this->used = false; + this->current_mo = NULL; + this->meta_object_list = NULL; + this->mclcb = mclcb; + this->completed = false; + this->metaobject_only_mode = false; +} + +/****************************************************************************** + * mcl_meta_object_layer Destructor. + */ +mcl_meta_object_layer::~mcl_meta_object_layer() +{ + struct list_of_meta_objects *temp; + + if (mclcb->is_a_sender()) + delete current_mo; + if (mclcb->is_a_receiver()) { + while(meta_object_list!=NULL) + { + temp = meta_object_list; + meta_object_list = meta_object_list->next; + delete temp->meta_obj; + free(temp); + } + } + mclcb = NULL; + this->current_mo = NULL; + this->used = false; + +} + + +/****************************************************************************** + * create_meta_object : creates a new MO. + * => See header file for more informations. + */ +void mcl_meta_object_layer::create_meta_object() +{ + if (!mclcb->is_a_sender()) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::create_meta_object: function can only be used at sender side")); + } + this->used = true; + this->completed = false; + current_mo = new mcl_meta_object(mclcb); +} + + +/****************************************************************************** + * add_object : adds an object to current the MO. + * => See header file for more informations. + */ +int mcl_meta_object_layer::add_object(struct mcl_msghdr *msg) +{ + int result; + TRACELVL(5, (mcl_stdout, "-> mcl_meta_object_layer::add_object\n")) + if (!mclcb->is_a_sender()) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::add_object: function can only be used at sender side")); + } + + if (current_mo==NULL) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::add_object: no meta object has been declared")); + } + + if ((msg->msg_iov == NULL) || (msg->msg_iovlen <= 0)) { + PRINT_ERR((mcl_stderr, + "mcl_meta_object_layer::add_object: ERROR: msg->msg_iov NULL or msg->msg_iovlen <= 0\n")) + return -1; + } + + + result = current_mo->add_object(msg); + TRACELVL(5, (mcl_stdout, "<- mcl_meta_object_layer::add_object\n")) + return result; +} + +/****************************************************************************** + * add_object : closes the current MO and sets its id. + * => See header file for more informations. + */ +void mcl_meta_object_layer::close_meta_object(UINT32 moid) +{ + char * odt; + char * data; + int len; + int toi; + int codec; + int old_codec; + float fec_ratio = 0; + float old_fec_ratio; + + struct mcl_iovec iov; + struct mcl_msghdr msg; + + + TRACELVL(5, (mcl_stdout, "-> mcl_meta_object_layer::close_meta_object\n")) + + if (!mclcb->is_a_sender()) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::close_meta_object: function can only be used at sender side")); + } + + if (current_mo == NULL) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::close_meta_object: no meta object has been declared")); + } + + this->completed = true; + + if (current_mo->nb_obj == 0) + { + /* No object has been submitted between + * MCL_OPT_KEEP_META_OBJECT and MCL_OPT_PUSH_META_OBJECT. + * Just delete the MO and do nothing */ + + delete current_mo; + current_mo = NULL; + + return; + } + + /* + * create a corresponding msg descriptor. + */ + memset((void*)&iov, 0, sizeof(iov)); + memset((void*)&msg, 0, sizeof(msg)); + msg.msg_name = NULL; + msg.msg_namelen = 0; + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + iov.iov_type = MCL_IOV_TYPE_BUFFER; + + /*save the old fec parameters*/ + old_codec = mclcb->fec.get_fec_code(); + old_fec_ratio = mclcb->fec.get_fec_ratio(); + + /* set the moid, then get ODT and submit it to MCL */ + current_mo->set_id(moid); + current_mo->get_object_description_table((char**)&odt, &len); + toi = 0; +#ifdef RSE_FEC + codec = MCL_FEC_SCHEME_RSE_129_0; + fec_ratio = 1.5; +#else + codec = MCL_FEC_SCHEME_NULL; +#endif + + mcl_ctl2(mclcb, MCL_OPT_SET_FEC_CODE, (void*)&codec, sizeof(codec)); + mcl_ctl2(mclcb, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, sizeof(fec_ratio)); + mcl_ctl2(mclcb, MCL_OPT_SET_NEXT_TOI, &toi, sizeof(int)); + mcl_ctl2(mclcb, MCL_OPT_SET_NEXT_ADU_HIGH_IMPORTANCE, NULL, 0); + iov.iov_base = (void*)odt; + iov.iov_len = len; + mcl_sendmsg2(mclcb, &msg, MCL_MSG_DEFAULT); + + /* get meta object data and submit it to MCL*/ + current_mo->get_meta_object_data((char**)&data, &len); + toi = moid; + mcl_ctl2(mclcb, MCL_OPT_SET_FEC_CODE, (void*)&old_codec, sizeof(old_codec)); + mcl_ctl2(mclcb, MCL_OPT_FEC_RATIO, (void*)&old_fec_ratio, sizeof(old_fec_ratio)); + mcl_ctl2(mclcb, MCL_OPT_SET_NEXT_TOI, &toi, sizeof(int)); + iov.iov_base = (void*)data; + iov.iov_len = len; + mcl_sendmsg2(mclcb, &msg, MCL_MSG_DEFAULT); + + delete current_mo; + current_mo = NULL; + + TRACELVL(5, (mcl_stdout, "<- mcl_meta_object_layer::close_meta_object\n")) + +} + +/****************************************************************************** + * add_object_description_table : allows to pass a received ODT to the MO_mgmnt layer. + * => See header file for more informations. + */ +void mcl_meta_object_layer::add_object_description_table(char* data, int len) +{ + + struct list_of_meta_objects *temp, *temp2, *new_obj; + UINT32 moid; + UINT32 moid_length; + + if (!mclcb->is_a_receiver()) + { + PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::add_object_description_table: function can only be used at receiver side")); + } + + /* get the length of moid */ + moid_length = ((*(UINT32*)data >> 24) & 0x0000000F); + if (moid_length != 2) PRINT_ERR((mcl_stderr, "mcl_meta_object_layer::add_object_description_table: ERROR, MOI size != 32bits not supported\n")) + + /* get the moid of the description table */ + moid = *(UINT32*)((char*)data + 4); + + /* check if moid is already in the list of meta objects */ + /* and create the new meta object if necessary */ + temp = temp2 = meta_object_list; + while(temp != NULL) + { + if (temp->meta_obj->get_id() == moid) break; + temp2 = temp; + temp = temp->next; + } + if (temp == NULL) + { + new_obj = (list_of_meta_objects*) malloc(sizeof(struct list_of_meta_objects)); + new_obj->meta_obj = new mcl_meta_object(data, len, mclcb); + new_obj->next = NULL; + + if ( temp2 != NULL) + { + temp2->next = new_obj; + } + else + { + meta_object_list = new_obj; + } + } + +} + +/****************************************************************************** + * check_for_decoded_objects : Checks if objects of the one of the known MO have been decoded. + * => See header file for more informations. + */ +int mcl_meta_object_layer::check_for_decoded_objects(struct mcl_msghdr *msg, enum mcl_msgflag flags) +{ + struct list_of_meta_objects *temp, *temp_prev; + int len; + + ASSERT(mclcb->is_a_receiver()); + temp_prev = NULL; + + /* goto last MO used with MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT + * otherwise begin with first MO in list. */ + if (current_mo != NULL) + { + temp = meta_object_list; + while (temp != NULL && temp->meta_obj != current_mo) + { + temp_prev = temp; + temp = temp->next; + } + current_mo = NULL; + } + else + { + temp = meta_object_list; + } + while (temp != NULL) + { + if ((len = temp->meta_obj->check_for_decoded_objects(msg, flags)) > 0) + { + /* we found an object */ + if ((flags == MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT)) + { + /* remember this MO in order to return the same object in + * next mcl_recv */ + current_mo = temp->meta_obj; + } + return len; + } + else if (len == -1) + { + /* meta object can be freed*/ + + if (temp_prev != NULL) + { + temp_prev->next = temp->next; + delete temp->meta_obj; + free(temp); + temp = temp_prev->next; + } + else + { + meta_object_list = temp->next; + delete temp->meta_obj; + free(temp); + temp = meta_object_list; + + } + } + else + { + /* move to next MO */ + temp_prev = temp; + temp = temp->next; + } + } + return 0; + +} + +/****************************************************************************** + * check_for_decoded_objects : Is id a known moid of a meta-object? + * => See header file for more informations. + */ +bool mcl_meta_object_layer::is_metaobj(UINT32 id) +{ + bool result = false; + struct list_of_meta_objects* temp; + + temp = meta_object_list; + while( temp != NULL) + { + if(id == temp->meta_obj->get_id()) + { + result = true; + break; + } + temp=temp->next; + } + + return result; +} + +#endif /* METAOBJECT_USED */ diff --git a/src/alc/mcl_meta_object_layer.h b/src/alc/mcl_meta_object_layer.h new file mode 100644 index 0000000..71f47c5 --- /dev/null +++ b/src/alc/mcl_meta_object_layer.h @@ -0,0 +1,161 @@ +/* $Id: mcl_meta_object_layer.h,v 1.12 2005/01/11 15:40:16 moi Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_META_OBJECT_LAYER /* { */ +#define MCL_META_OBJECT_LAYER + +typedef struct list_of_meta_objects { + class mcl_meta_object *meta_obj; /* Metaobject*/ + struct list_of_meta_objects *next; /* next metaobject in list */ +} list_of_meta_objects_t; + + + +class mcl_meta_object_layer { + +public: + + /****** Public Members ************************************************/ + /** + * Constructor. + * @param mclcb (IN) mclcb. + */ + mcl_meta_object_layer (class mcl_cb* mclcb); + + /** Destructor */ + ~mcl_meta_object_layer (); + + /** + * Create a new meta-object at a sender. + * Only at sender side. + */ + void create_meta_object (); + + /** + * Adds an object to the current meta-object. + * Is usually called after a mcl_meta_object (char* odt, int odt_len, class mcl_cb * mclcb). + * Only at sender side. + * @param msg (IN) Message control structure describing the object + * @return <0 if error. + */ + int add_object(struct mcl_msghdr *msg); + + /** + * Closes the current meta object, sets its id moid and + * submits it and submits the associated ODT. + * Only at sender side. + * @param id of the current MO. + */ + void close_meta_object (UINT32 moid); + + /** + * This function allows to pass a received ODT to the MO_mgmnt layer. + * It created the corresponding MO. + * Only at receiver side. + * @param pointer to the ODT + * @param length in bytes of the ODT + */ + void add_object_description_table (char* data, int len); + + + /** + * This function checks if objects of the one of the known MO have been decoded. + * It returns the length of the object and 0 if no object is available. + * MO can be deleted that have delivered all their object are deleted by + * this function. + * Only at receiver side + * @param msg pointer to the mcl_msghdr structure. + * @param flags flags to control some specific features. + * @return number of bytes received (or available if + * MCL_MSG_GET_SIZE_OF_AVAILABLE_OBJECT or MCL_PEEK is used), + * 0 if no objects are ready. + */ + int check_for_decoded_objects (struct mcl_msghdr *msg, enum mcl_msgflag flags); + + /** + * Is id a known moid of a meta-object? + * Only at receiver side. + * @param id of the moid + * @return true if in it is a known moid, false otherwise. + */ + bool is_metaobj (UINT32 id); + + /** + * Returns true is the meta-object service is in use. + * @return true if in use, false otherwise. + */ + bool in_use(); + + + /** + * Set the meta-object service as is in use or not. + * @param true = in use, false = not in use + */ + void set_in_use(bool in_use); + + + /****** Public Attributes ********************************************/ + /* TODO: make them private and use functions set/get_attribute */ + /** The currently submitted metaobject is completed (at a sender). */ + bool completed; + + /* true if all ADU send or received objects are meta objects */ + bool metaobject_only_mode; + +private: + /****** Private Attributes ********************************************/ + /** true if meta-object service in use */ + bool used; + + /** + * At a sender, this is the currently submitted metaobject, and + * at a receiver, this is the last metaobject that had an object + * ready at last MCL_MSG_GET_SIZE_OF_AVAILABLE_OBJECT + * or MCL_MSG_PEEK. + */ + class mcl_meta_object *current_mo; + + /** list of existing non-decoded meta objects (only at receiver). */ + struct list_of_meta_objects *meta_object_list; + + class mcl_cb *mclcb; +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +inline bool +mcl_meta_object_layer::in_use() +{ + return this->used; +} + + +inline void +mcl_meta_object_layer::set_in_use(bool in_use) +{ + this->used = in_use; +} + +#endif /* } MCL_METAOBJ_LAYER_H */ diff --git a/src/alc/mcl_network.cpp b/src/alc/mcl_network.cpp new file mode 100644 index 0000000..d6842ea --- /dev/null +++ b/src/alc/mcl_network.cpp @@ -0,0 +1,484 @@ +/* $Id: mcl_network.cpp,v 1.30 2005/03/18 12:06:17 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * Network functions (lower socket interface). + */ + +#include "mcl_includes.h" + + +#ifdef SIMUL_LOSSES +/* + * Simulate packets losses randomly + * Returns 0 if OK, 1 if packet should be lost... + */ +static int RandomLoss(mcl_cb *mclcb, + int layer) +{ + int IsLost = 0; + + TRACELVL(5, (mcl_stdout, "-> RandomLoss\n")) + switch ( mclcb->simul_losses_state ) { + case 0: /* last packet was sent OK. */ +#ifdef CONSTANT_LOSS_RATIO + if ((float)(random()%100) < (float)P_LOSS_WHEN_OK) +#else + if ((float)(random()%100) < (P_LOSS_WHEN_OK*(float)layer)) +#endif + { + IsLost = 1; + mclcb->simul_losses_state = 1; + } + break; + case 1: /* last packet was lost */ +#ifdef CONSTANT_LOSS_RATIO + if ((float)(random()%100) < (float)P_LOSS_WHEN_LOSSES) +#else + if ((float)(random()%100) < (P_LOSS_WHEN_LOSSES*(float)layer)) +#endif + { + IsLost = 1; + } + else + mclcb->simul_losses_state = 0; + break; + default: + perror("RandomLoss: unknown state"); + mcl_exit(1); + break; + } + TRACELVL(5, (mcl_stdout, "<- RandomLoss (layer:%d, IsLost:%d)\n", layer, IsLost)) + if (IsLost) + mclcb->stats.tx_simul_loss_lost++; + else + mclcb->stats.tx_simul_loss_sent++; + return IsLost; +} +#endif /* SIMUL_LOSSES */ + + + +/* + * Create and send a packet (with/without data and/or SIG) immediately + * Returns 0 if OK, < 0 otherwise. + */ +int +mcl_send_pkt (mcl_cb *mclcb, + int layer, + du_t *du, + adu_t *adu) +{ + block_t *blk; + mcl_socket *so; +#define PBUF_LEN (MAX_DATAGRAM_SIZE) + /* DU (hdr+data) cant be larger than PBUF_LEN */ + char buf[PBUF_LEN]; + fixed_lct_hdr_t *lct_hdr; /* fixed size LCT header */ + hdr_infos_t hdr_infos; /* struct given to LCT creation funcs */ + int hlen; /* total (RLC/FLIDS+LCT) header length*/ + int len; + int sig_nb; /* SIG # sent in this packet */ + MCL_IOVEC iov[2]; /* to describe header + data */ +#ifdef WIN32 + struct sockaddr *msg_name; + UINT32 msg_namelen; + DWORD nb_sent=0; +#else + struct msghdr msg; /* for the sendmsg() Socket syscall */ +#endif + + TRACELVL(5, (mcl_stdout, "-> mcl_send_pkt: layer=%d, du=x%x, adu=x%x\n", + layer, (int)du, (int)adu)) + /* prepare for new sig copies */ + so = mclcb->txlay_tab[layer].socket; + /* reset hdr_infos */ + memset(&hdr_infos, 0, sizeof(hdr_infos)); + hdr_infos.TOI_present = hdr_infos.FPI_present + = hdr_infos.FDT_present + = hdr_infos.FTI_present + = hdr_infos.NONEWADU_present + = false; +#ifdef METAOBJECT_USED + hdr_infos.MODT_present = false; +#endif + if (du) { + ASSERT(adu); /* also required in that case */ + blk = du->block; + ASSERT(blk); + hdr_infos.TOI_present = true; + hdr_infos.idf_adu = adu->seq; + hdr_infos.idf_block = blk->seq; + hdr_infos.idf_du = du->seq; +#ifdef FEC + hdr_infos.is_fec = du->is_fec; +#endif /* FEC */ + /* ADU seq == 0 sometimes require special handling... */ + if (adu->seq == 0) { + if (mclcb->is_flute_compatible() == true) { + /* it's the file delivery table, FDT */ + hdr_infos.FDT_present = true; + hdr_infos.FDT_instanceid = adu->FDT_instanceid; + + } +#ifdef METAOBJECT_USED + else if (mclcb->meta_obj_layer->in_use() == true) { + /* it's the meta object descr table, MODT */ + hdr_infos.MODT_present = true; + hdr_infos.FDT_instanceid = adu->FDT_instanceid; + } +#endif + } + hdr_infos.FPI_present = true; /* add FPI (required if data) */ + hdr_infos.demux_label = mclcb->demux_label; + hdr_infos.fec_encoding_id = adu->fec_encoding_id; + hdr_infos.fec_instance_id = adu->fec_instance_id; +#if 0 + /* don't add any FTI HE with RSE for packets sent on layer 3 + * and above */ + if (adu->fec_instance_id == FEC_INSTANCE_RSE && layer >= 3) { + hdr_infos.FTI_present = false; + } else { +#endif + hdr_infos.FTI_present = true; + hdr_infos.adu_len = adu->len; + hdr_infos.k = blk->k; /* current blk */ + hdr_infos.max_k = adu->max_k; + hdr_infos.max_n = adu->max_n; + hdr_infos.symbol_len = adu->symbol_len; +#ifdef LDPC_FEC + hdr_infos.fec_key = blk->fec_key; +#endif + /*}*/ + len = du->len; + } else { + + /* add some required flags, even if there is no data */ + hdr_infos.demux_label= mclcb->demux_label; + hdr_infos.fec_encoding_id = FEC_ENCODING_ID_NO_FEC;/* no FEC */ + hdr_infos.fec_instance_id = 0; /* no FEC */ + len = 0; + } + + /* + * Prepar signaling header extensions to be added to the LCT header. + * There is enough room for 16 bytes of additional signaling header + * extensions (in particular for NONEWADU). + */ + CopySigReset(mclcb); + sig_nb = CopySigToLCTinfos(mclcb, layer, &hdr_infos, 16); + CleanupSigTab(mclcb); + /* + * create the ALC/LCT headers now + * NB: hlen includes both ALC, LCT and RLC/FLIDS headers! + */ + lct_hdr = (fixed_lct_hdr_t*)buf; + hlen = alc_hdr_create(mclcb, lct_hdr, (hdr_infos_t*)&hdr_infos); + if (hlen < 0) + goto bad; + ASSERT(hlen <= MAX_ALC_HEADER_SIZE); /* make sure... */ + /* + * create the appropriate congestion control header + */ + if (mclcb->congestion_control == NO_CC) { + /* + * In no cogestion control mode there is no CC header. + * Required for FLUTE interoperability tests, but a limitation + * is that no loss statistics are possible + */ + lct_hdr->cci = 0; + } +#ifdef RLC + else if (mclcb->congestion_control == RLC_CC) { + if (rlc_tx_fill_header(mclcb, (rlc_hdr_t*)&(lct_hdr->cci), + (UINT8) layer) != MCL_OK) + goto bad; +#endif +#ifdef FLIDS + } else if (mclcb->congestion_control == FLID_SL_CC) { + if (FLIDs_tx_FillHeader(mclcb, (flids_hdr_t*)&(lct_hdr->cci), + (UINT8)layer ) != MCL_OK) + goto bad; + } +#endif + /* + * update traces and statistics + */ + if (mclcb->get_verbosity() >= 2) { + mcl_print_sent_du(mclcb, 0, layer, &hdr_infos); + if (mclcb->get_verbosity() >= 5) { + /* header and data are in two diff buffers */ + mcl_dump_buffer(buf, hlen, (hlen>> 2)); + /*mcl_dump_buffer(du->data, len, (len >> 2));*/ + } + } + if (len > 0) { + if (hdr_infos.is_fec) { + mclcb->stats.tx_fec_pkts++; + mclcb->stats.tx_fec_bytes += len; + } else { + mclcb->stats.tx_pkts++; + mclcb->stats.tx_bytes += len; + } + mclcb->stats.tx_pkts_per_lvl[layer]++; + mclcb->stats.tx_bytes_per_lvl[layer] += len; + } + mclcb->stats.tx_totbytes += hlen + len; + /* + * and now send the packet + */ + MCL_IOV_BUFF(iov[0]) = buf; + MCL_IOV_LEN(iov[0]) = hlen; + if (len > 0) { +#ifdef VIRTUAL_TX_MEM + /* make sure data is in phy mem (perhaps in VTM cache) first */ + mcl_vtm_get_data(mclcb, du); + ASSERT(du->data); +#endif /* VIRTUAL_TX_MEM */ + MCL_IOV_BUFF(iov[1]) = du->data; + MCL_IOV_LEN(iov[1]) = len; + } else { + /* security */ + MCL_IOV_BUFF(iov[1]) = NULL; + MCL_IOV_LEN(iov[1]) = 0; + } + +#ifdef WIN32 + if (adu && adu->addr_valid) { + /* use this dest addr */ + msg_name = (struct sockaddr*) adu->addr.get_internal_struct_addr(); + msg_namelen = adu->addr.get_addr_struct_len(); + } else { + /* use the default dest addr */ + msg_name = (struct sockaddr*) so->addr.get_internal_struct_addr(); + msg_namelen = so->addr.get_addr_struct_len(); + } +#else /* UNIX */ + memset(&msg, 0, sizeof(msg)); + if (adu && adu->addr_valid) { + /* use this dest addr */ + msg.msg_name = (char*)(adu->addr.get_internal_struct_addr()); + msg.msg_namelen = adu->addr.get_addr_struct_len(); + } else { + /* use the default dest addr */ + msg.msg_name = (char*)(so->addr.get_internal_struct_addr()); + msg.msg_namelen = so->addr.get_addr_struct_len(); + } + msg.msg_iov = iov; + msg.msg_iovlen = (len > 0 ? 2 : 1); +#endif /* OS_DEP */ + +#ifdef SIMUL_LOSSES + if (!RandomLoss(mclcb,layer)) { +#endif /* SIMUL_LOSSES */ +#ifdef WIN32 + if (WSASendTo(so->priv_sock, iov, (len > 0 ? 2 : 1), &nb_sent, 0, + msg_name, msg_namelen, NULL, NULL) == SOCKET_ERROR) { + PRINT_ERR((mcl_stderr,"mcl_send_pkt: WSASendTo (code:%d - sock:%d)\n", WSAGetLastError(), so->priv_sock)) + mcl_exit(1); + } +#else /* UNIX */ + if (sendmsg(so->priv_sock, &msg, 0) != hlen + len) { + perror("mcl_send_pkt: sendmsg"); + PRINT_ERR((mcl_stderr, + "mcl_send_pkt: ERROR, sendmsg failed; priv_sock=%d, family=%d, dst=%s/%d, hlen=%d, len=%d\n", + so->priv_sock, + ((struct sockaddr_in*)(msg.msg_name))->sin_family, + /* TODO: the following line is only for IPv4! */ + inet_ntoa(((struct sockaddr_in*)(msg.msg_name))->sin_addr), + ntohs(((struct sockaddr_in*)(msg.msg_name))->sin_port), + hlen, len)) + + mcl_exit(1); + } +#endif /* OS_DEP */ + if (mclcb->get_verbosity() >= 4) { +#ifdef WIN32 + PRINT_OUT((mcl_stdout, + "sendmsg: priv_sock=%d, family=%d, dst=%s/%d, hlen=%d, len=%d\n", + (int)so->priv_sock, + ((struct sockaddr_in*)msg_name)->sin_family, + inet_ntoa(((struct sockaddr_in*)msg_name)->sin_addr), + ntohs(((struct sockaddr_in*)msg_name)->sin_port), + hlen, len)) +#else /* UNIX */ + PRINT_OUT((mcl_stdout, + "sendmsg: priv_sock=%d, family=%d, dst=%s/%d, hlen=%d, len=%d\n", + so->priv_sock, + ((struct sockaddr_in*)(msg.msg_name))->sin_family, + inet_ntoa(((struct sockaddr_in*)(msg.msg_name))->sin_addr), + ntohs(((struct sockaddr_in*)(msg.msg_name))->sin_port), + hlen, len)) +#endif /* OS_DEP */ + } +#ifdef SIMUL_LOSSES + } else { + TRACELVL(3, (mcl_stdout, "=> Random Loss on layer %d\n", layer)) + } +#endif /* SIMUL_LOSSES */ + //len = 0; /* no data to send next time */ + TRACELVL(5, (mcl_stdout, "<- mcl_send_pkt:\n")) + return 0; + +bad: + TRACELVL(5, (mcl_stdout, "<- mcl_send_pkt: ERROR\n")) + return -1; +#undef PBUF_LEN +} + + +/* + * Receive a new packet + * Returns the packet len if ok, -1 if error + */ +void +mcl_recv_pkt (mcl_cb *mclcb) +{ + /* + * using MAX_ETHERNET_SIZE is usefull if the datagram + * size may change during the session or it is unknown + */ + //#define PBUF_LEN (mclcb->payload_size + MAX_ALC_HEADER_SIZE) +#define PBUF_LEN (MAX_ETHERNET_MTU - UDP_IPv4_HEADER_SIZE) + + mcl_rx_pkt *pkt; // recv'd packet buffer + struct sockaddr_storage saddr; /* buffer for src addr or NULL */ + int saddr_len; /* src addr len */ + class mcl_addr addr; + mcl_socket *so; + int n; + int lay; + fd_set tmp_fds; + struct timeval tv; /* don't wait indefinitely in select */ + + TRACELVL(5, (mcl_stdout, "-> mcl_recv_pkt:\n")) +again: + /* + * wait to receive packets... a select on several fd is required! + */ + if (mclcb->rxlvl.n_fd == 0) { + /* nothing to select, return! */ + return; + } + tmp_fds = mclcb->rxlvl.fds; + tv.tv_sec = 1; /* wait at most 1s to have opportunity to update fds */ + tv.tv_usec = 0; + mclcb->unlock(); + mcl_thread_testcancel(mclcb); + if ((n = select(mclcb->rxlvl.nfds, &tmp_fds, NULL, NULL, &tv)) < 0) { + /* always try again in practice */ + mclcb->lock(); + goto again; + } + mcl_thread_testcancel(mclcb); + mclcb->lock(); + if (n == 0) { + /* nothing received */ + TRACELVL(5, (mcl_stdout, "<- mcl_recv_pkt: timeout\n")) + return; + } + /* + * read the packet(s) received (there may be more than one!) + */ + //if (n > 0) PRINT_OUT((mcl_stdout, "select returned n=%d\n", n)) + for (lay = 0, so = mclcb->socket_tab; + lay < mclcb->mcl_max_group; + lay++, so++) { + if (mcl_is_valid_sock(so->ses_sock) && + FD_ISSET((int)so->ses_sock, &tmp_fds)) { + while (mcl_is_valid_sock(so->ses_sock)) { + pkt = new mcl_rx_pkt(PBUF_LEN); + ASSERT(pkt); + saddr_len = sizeof(saddr); + memset(&saddr, 0, sizeof(saddr)); + pkt->pkt_len = recvfrom(so->ses_sock, + pkt->get_buf(), pkt->get_buf_len(), + 0, (sockaddr *) &saddr, +#if defined(LINUX) || defined(AIX) + (size_t*) +#elif defined(FREEBSD) + (socklen_t*) +#endif + &saddr_len); +#ifdef WIN32 + if(pkt->pkt_len == SOCKET_ERROR || pkt->pkt_len == 0) { + /* we are in non-blocking mode! */ + if (WSAGetLastError() == WSAEWOULDBLOCK || WSAGetLastError() == WSAENOTSOCK) { + /* no ready packet anymore */ + delete pkt; + break; + } /* else exit... */ + PRINT_ERR((mcl_stderr, "mcl_recv_pkt: ERROR, ses_sock=%d, error=%d\n", so->ses_sock, WSAGetLastError())) + mcl_exit(1); + } +#elif defined(SOLARIS) + if (pkt->pkt_len < 0) { + /* we are in non-blocking mode! */ + /* I cannot check errno reliably on + * Solaris but I don't know why! */ + /* XXX: assume no ready packet anymore*/ + delete pkt; + break; + } +#else /* LINUX */ + if (pkt->pkt_len < 0) { + /* we are in non-blocking mode! */ + if (errno == EAGAIN || errno == EWOULDBLOCK) { + /* no ready packet anymore */ + delete pkt; + break; + } /* else exit... */ + TRACELVL(5, (mcl_stdout, "mcl_recv_pkt: ERROR, ses_sock=%d, error=%d\n", so->ses_sock, errno)) + perror("mcl_recv_pkt: recvfrom"); + mcl_exit(1); + } +#endif /* OSDEP */ + if (saddr.ss_family == AF_INET) + { + addr.set_addr_struct((struct sockaddr_in*)&saddr); + } +#ifdef INET6 + else if (saddr.ss_family == AF_INET6) + { + addr.set_addr_struct((struct sockaddr_in6*)&saddr); + } +#endif + /* and finally process the packet */ + mcl_process_pkt (mclcb, pkt, &addr, lay); + +#if 0 /* removed to catch duplicated pkt, see above */ + /* + * try again only on layers >= 2 where we know + * we can receive more than 2 pkts per cycle + */ + if (lay <= 1) + break; +#endif + } + } + mclcb->unlock(); + mcl_thread_testcancel(mclcb); + mclcb->lock(); + } + TRACELVL(5, (mcl_stdout, "<- mcl_recv_pkt: \n")) +#undef PBUF_LEN +} + diff --git a/src/alc/mcl_periodic_proc.cpp b/src/alc/mcl_periodic_proc.cpp new file mode 100644 index 0000000..0ee7700 --- /dev/null +++ b/src/alc/mcl_periodic_proc.cpp @@ -0,0 +1,236 @@ +/* $Id: mcl_periodic_proc.cpp,v 1.5 2005/05/18 14:37:56 roca Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +mcl_periodic_proc::mcl_periodic_proc () +{ + /** Time_count of last do_periodic_proc call. */ + this->last_periodic_proc_tc = 0; + /** itimer of last do_periodic_proc call. */ + this->last_periodic_proc_it = 0; + /** fractional tick_nb in do_periodic_proc. */ + this->remaining_tx_tick_nb = 0.0; +} + + +mcl_periodic_proc::~mcl_periodic_proc () +{ +} + + +void +mcl_periodic_proc::scan_all_sessions (void) +{ + INT32 ses; // session id + mcl_cb *mclcb; // session control block +#ifdef GET_SYSINFO + mcl_cb *mclcb_tmp = NULL;/* remember a valid mclcb */ + INT32 mcl_sysinfo_count = MCL_SYSINFO_PERIOD / MCL_PERIODIC_TIMER_PERIOD; +#endif + + /* + * scan all the sessions + */ + for (ses = 0; ses < MAX_NB_MCLCB; ses++) { + if ((mclcb = mclcb_tab[ses]) == NULL) + continue; /* unused entry! */ + mclcb->lock(); + if (!mclcb->is_fully_initialized()) { + mclcb->unlock(); + continue; + } + TRACELVL(6, (mcl_stdout, "mcl_periodic_proc::scan_all_sessions: time_count=%d, ses=%d, states=%s/%s\n", + mcl_time_count, ses, + mclcb->fsm.print_tx_state(mclcb), + mclcb->fsm.print_rx_state(mclcb))) + /* everything is done here... */ + mclcb->periodic_proc.do_periodic_proc(mclcb); +#ifdef GET_SYSINFO + mclcb_tmp = mclcb; /* remember for GET_SYSINFO needs */ +#endif + mclcb->unlock(); + } +#ifdef GET_SYSINFO + /* + * print system information if required + * precise timing is not required here... + */ + if (mclcb_tmp && mclcb_tmp->verbose == 2 && --mcl_sysinfo_count == 0) { + /* one trace every approx. MCL_SYSINFO_PERIOD usec */ + mcl_print_sysinfo(mclcb_tmp); + mcl_sysinfo_count = MCL_SYSINFO_PERIOD / MCL_PERIODIC_TIMER_PERIOD; + } +#endif /* GET_SYSINFO */ +} + + +void +mcl_periodic_proc::do_periodic_proc (mcl_cb *mclcb) +{ + //mcl_periodic_timer_var *timer_var; // class containing per session var + mcl_itime_t now; /* current itime */ + mcl_itime_t elit; /* elasped itime since last call */ + INT32 eltc; /* elasped time_count since last call */ + double true_tx_tick_nb;/* tx tick elapsed as a float */ + INT32 tx_tick_nb; /* integral part of true_tx_tick_nb */ + + ASSERT(mclcb->is_fully_initialized()); + TRACELVL(5, (mcl_stdout, "-> mcl_periodic_proc::mcl_do_periodic_proc: mclcb=x%x\n", (int)mclcb)) + + //timer_var = &(mclcb->periodic_timer_var); + now = mcl_get_itime(); + //if (timer_var->last_periodic_proc_tc == 0) + if (this->last_periodic_proc_tc == 0) { + /* first call for this mclcb => timing initialization */ + this->last_periodic_proc_it = now; + this->last_periodic_proc_tc = mcl_time_count; + this->remaining_tx_tick_nb = 0.0; + } + /* + * elapsed time + */ + elit = mcl_itime_sub(now, this->last_periodic_proc_it); + this->last_periodic_proc_it = now; + /* + * elapsed time_count since last call + * NB: no fractional part here, done in mcl_timer_thread + */ + eltc = mcl_time_count - this->last_periodic_proc_tc; + this->last_periodic_proc_tc = mcl_time_count; + + /* + * RLC periodic processing + */ +#ifdef RLC + if (mclcb->is_a_receiver() && mclcb->congestion_control == RLC_CC && + eltc > 0) { + /* update counter */ + mclcb->rlccb.rlc_rx_timer_count -= eltc; + /* call rlc_rx_timer as many times as required if eltc large */ + while (mclcb->rlccb.rlc_rx_timer_count < 0) { + rlc_rx_timer(mclcb); + mclcb->rlccb.rlc_rx_timer_count += + mcl_rlc_rx_period / MCL_PERIODIC_TIMER_PERIOD; + } + } +#endif + /* + * FLID-SL periodic processing + */ +#ifdef FLIDS + if (mclcb->is_a_sender() && mclcb->congestion_control == FLID_SL_CC && + eltc > 0) { + /* update counter */ + mclcb->flids_cb.flids_tx_timer_count -= eltc; + /* call flids_tx_timer as many times as required if eltc large*/ + while (mclcb->flids_cb.flids_tx_timer_count < 0) { + FLIDs_TxTimer(mclcb); + mclcb->flids_cb.flids_tx_timer_count += + mclcb->flids_cb.tsd / MCL_PERIODIC_TIMER_PERIOD; + } + } +#endif + /* + * periodic transmissions + */ + if (mclcb->is_a_sender()) { + /* + * how many tx ticks since last call? + * first calculate the float tick nb, then its integral part, + * and remember the decimal part for next time + */ + true_tx_tick_nb = (double) + (mcl_it2sec(elit) / mcl_periodic_timer::get_period() + + this->remaining_tx_tick_nb); + tx_tick_nb = (INT32)(true_tx_tick_nb); + this->remaining_tx_tick_nb = true_tx_tick_nb - (double)tx_tick_nb; + if (mcl_periodic_timer::must_reduce_activity()) { + /* + * when in "no_time_to_sleep" mode, limit the + * tx_tick_nb to try to solve the problem... + */ + tx_tick_nb = 1; + } else { + /* limit tx_tick_nb anyway to avoid large tx bursts + * unless we are in singlelayer mode in which case + * the number of packets may indeed be quite large + * on the single transmission layer */ + if (!(mclcb->single_layer_mode)) { + tx_tick_nb = min(tx_tick_nb, 5); + } + + } + /* call the tx function for each tx_tick */ + for (int i = tx_tick_nb; i > 0; i--) { + mclcb->tx.try_to_send(mclcb); + } + } + +#if 0 // not yet + /* + * launch memory cleanup function periodically + */ + if (mclcb->is_a_sender() && mclcb->delivery_mode == DEL_MODE_STREAMING +#ifdef VIRTUAL_TX_MEM + && !(mclcb->vtm_used) +#endif /* VIRTUAL_TX_MEM */ + && eltc > 0) { + /* update counter */ + mclcb->tx_mem_cleanup_count -= eltc; + if (mclcb->tx_mem_cleanup_count < 0) { + mclcb->tx_mem_cleanup_count = + TX_MEM_CLEANUP_PERIOD / MCL_PERIODIC_TIMER_PERIOD; + mcl_tx_cleanup(mclcb); + } + } +#endif + +#if 0 + /* + * print stats periodically + */ + if (mclcb->statistics == 2) { + mclcb->stats_time_count -= eltc; + if (mclcb->stats_time_count < 0) { + mclcb->stats_time_count = STATS_PERIOD / MCL_PERIODIC_TIMER_PERIOD; + if (mclcb->sender) + mcl_print_tx_stats(mclcb); + if (mclcb->receiver) + mcl_print_rx_stats(mclcb); + /* nb: stats_period is init'ed in func*/ + } + //mclcb->stat_rem_it = mcl_itime_sub(mclcb->stat_rem_it, elit); + //if (mcl_itime_leq_0(mclcb->stat_rem_it)) { + // mclcb->stat_rem_it = mcl_user2it(); + // if (mclcb->sender) + // mcl_print_tx_stats(mclcb); + // if (mclcb->receiver) + // mcl_print_rx_stats(mclcb); + // /* nb: stats_period is init'ed in func*/ + //} + } +#endif // 0 + + TRACELVL(5, (mcl_stdout, "<- mcl_periodic_proc::mcl_do_periodic_proc:\n")) +} + diff --git a/src/alc/mcl_periodic_proc.h b/src/alc/mcl_periodic_proc.h new file mode 100644 index 0000000..b0f7084 --- /dev/null +++ b/src/alc/mcl_periodic_proc.h @@ -0,0 +1,93 @@ +/* $Id: mcl_periodic_proc.h,v 1.2 2005/05/18 14:37:56 roca Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_PERIODIC_PROC_H +#define MCL_PERIODIC_PROC_H + + +/** + * This class gathers additional variables and member functions that are + * specific to each MCL session. This class is included by mcl_cb class. + */ +class mcl_periodic_proc { + +public: + /****** Public Members ************************************************/ + + /** + * Default constructor. + */ + mcl_periodic_proc (); + + /** + * Default destructor. + */ + ~mcl_periodic_proc (); + + /** + * Scan all the MCL sessions. + * Called periodically, unlocked, by the mcl_periodic_timer thread. + * There is only one instance of this function since it is + * independant of the MCL session. + */ + static void scan_all_sessions (void); + + /** + * Calls the various functions that perform periodic processing for + * a given session. + * Called by scan_all_sessions() for each valid mcl_cb, and also + * called (locked), by mcl_send(to)() to anticipate data + * transmissions while doing FEC encoding. + * @param mclcb session considered + */ + void do_periodic_proc (mcl_cb *mclcb); + + + /****** Public Attributes *********************************************/ + + /** Time_count of last do_periodic_proc call. */ + INT32 last_periodic_proc_tc; + /** itimer of last do_periodic_proc call. */ + mcl_itime_t last_periodic_proc_it; + /** Fractional tick_nb in do_periodic_proc. */ + double remaining_tx_tick_nb; + +#if 0 + /** tx memory cleanup function call counter. */ + int tx_mem_cleanup_count; + /** periodic stats print counter. */ + int stats_time_count; +#endif // 0 + +private: + /****** Private Members ***********************************************/ + + /****** Private Attributes ********************************************/ + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +#endif // !MCL_PERIODIC_PROC_H diff --git a/src/alc/mcl_profile.h b/src/alc/mcl_profile.h new file mode 100644 index 0000000..ea02438 --- /dev/null +++ b/src/alc/mcl_profile.h @@ -0,0 +1,404 @@ +/* $Id: mcl_profile.h,v 1.44 2005/05/23 14:35:54 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * This file contains all the parameters/constants/preprocessing flags + * controlling the profile of the MCL library. Edit as appropriate... + * Most of the values given here can be further modified using mcl_ctl(). + * + * Of course this file must be the first one included!!! + */ + +#ifndef MCL_PROFILE_H /* { */ +#define MCL_PROFILE_H + + +/****** ALC profile options ***************************************************/ + +/* + * Do you want IPv6 support? + */ +#define INET6 + + +/* + * Do you want SSM (Source Specific Multicast) support? + */ +#define SSM + + +/* + * Do you want physical object aggregation support? + */ +#define METAOBJECT_USED + + +#if 0 // not yet +/* + * Do you want to enable the use of Virtual Transmission Memory service? + * Really really recommanded if you deal with very large files. + */ +/* NB: mode set by default in each new session if you define VIRTUAL_TX_MEM */ +//#define VIRTUAL_TX_MEM +#ifdef VIRTUAL_TX_MEM +/* + * what is the maximum size of the physical memory area before storing data + * on disk? Adjust according to your desires/available physical memory... + */ +const INT32 VIRTUAL_TX_MEM_MAX_BUFFERING_SIZE = 30*1024*1024; +//const INT32 VIRTUAL_TX_MEM_MAX_BUFFERING_SIZE = 100*1024*1024; +#endif +#endif // 0 + + +/* + * Do you want to enable the use of Virtual Reception Memory service? + * Really really recommanded if you deal with very large files. + */ +/* NB: mode set by default in each new session if you define VIRTUAL_RX_MEM */ +#define VIRTUAL_RX_MEM + +#ifdef VIRTUAL_RX_MEM +/* + * what is the maximum size of the physical memory area before storing data + * on disk? Adjust according to your desires/available physical memory... + */ +const INT32 VIRTUAL_RX_MEM_MAX_BUFFERING_SIZE = 10*1024*1024; +//const INT32 VIRTUAL_RX_MEM_MAX_BUFFERING_SIZE = 100*1024*1024; + +/** + * Do you want to enable several receivers to use the VRMEM on the + * same host simultaneously or not? + * If enabled, then each VRM temporary file will be given a different + * file name, otherwise the same name will be used. + * By default we use the same name, since in case of crash, this temporary + * file will be overwritten automatically (instead of having several old + * versions, that take more andmore place). + * The downside is that there can be at most a single receiver per host, + * otherwise crashes will result (several receivers will access the same + * file simultaneously...). + */ +#define VIRTUAL_RX_MEM_SINGLE_RECEIVER_PER_HOST_MODE +#endif + + +/* + * Do you want to use congestion control (derived from RLC, + * Receiver Driver Layered Congestion Control Scheme) or not ? + */ +#define RLC + + +/* + * Do you want to use FLID Static Layer congestion control module or not ? + */ +#define FLIDS + + +/* + * Do you want to use Reed-Solomon Forward Error Correction (FEC) ? + */ +#define RSE_FEC + + +/* + * Do you want to use LDPC large block Forward Error Correction (FEC) ? + * Highly recommended when sending large objects... + */ +#define LDPC_FEC + +#if defined(RSE_FEC) || defined(LDPC_FEC) +#define FEC +#endif + + +/* + * by default, do you want to postpone FEC decoding at a receiver or not? + * it is recommended to postpone with very high speed reception rates and/or + * slow CPUs. + * + * WARNING: do not use if you have many independant tx to do as the receiver + * will be blocked, waiting for the end of all the tx. + */ +/*#define POSTPONE_FEC_DECODING*/ + + +/* + * an optimization for transmissions in PUSH mode. + * highly recommended! + */ +#define ANTICIPATED_TX_FOR_PUSH +#ifdef ANTICIPATED_TX_FOR_PUSH +/* + * select an aggressiveness. + * depends on the receivers capabilities, and the desire to favor some + * of them (low-end receivers versus high-end receivers) + */ +//#define ANTICIPATED_TX_FOR_PUSH_AGGRESSIVENESS 3 /* favors low-end rx */ +#define ANTICIPATED_TX_FOR_PUSH_AGGRESSIVENESS 4 /* default */ +//#define ANTICIPATED_TX_FOR_PUSH_AGGRESSIVENESS 5 /* favors high-end rx */ +#endif /* ANTICIPATED_TX_FOR_PUSH */ + + +/* + * What scheduling algorithm(s) do you need (there can be more than 1) ? + */ +/* + * LCT_SCHED1 + * transmit all the original+FEC DUs on each layer in a random order + * NB: now required since it is the only scheduling left! + */ +#define LCT_SCHED1 + + + +/****** MCL lib profile options ***********************************************/ + + +/** + * Max number of sessions per instance of the MCL library. + * Large numbers are possible if you have enough memory, disk space and CPU + * power ;-) + * Note that some systems (e.g. solaris) are more strict on the default + * maximum number of sockets in use. + * Note also that setting MCLCB_MAX_ID to a certain value does not mean + * that you can open up to this value, because of the way IDs are allocated + * (see mcl_cb::mcl_cb). To get a unique ID in the file descriptor space, + * we duplicate stdin and use the returned value. Therefore, since file + * descriptors 0, 1, and 2 are already allocated, MCLCB_MAX_ID should be + * at least equal to 3, or more if the upper application has opened one + * or more file descriptors. + */ +const INT32 MAX_NB_MCLCB = 20; + + +#ifdef FEC +/* + * parameters associated to the use of FEC: + * - maximum value of k for (k,n) FEC codecs; this is also the number + * of source symbols (i.e. of DUs) per block + * - maximum value of n for (k, n) FEC codecs; n-k is also the maximum number + * of FEC symbols that can be generated per block + * - FEC redundancy, or n/k ratio; e.g. 1.5 for 50% of FEC, 2.0 for 100% + * which is a by product of setting the k and n parameters + */ +#ifdef RSE_FEC +#define RSE_MAX_K GF_SIZE /* at most max_k DUs per source block */ +#define RSE_MAX_N GF_SIZE /* at most max_n DUs after encoding */ +const INT32 RSE_DEFAULT_K = 64; /* default */ +const INT32 RSE_DEFAULT_N = 128; /* default */ +#endif +#ifdef LDPC_FEC +const INT32 LDPC_MAX_K = 200*1000; /* at most 200*10^3 packets per block */ +const INT32 LDPC_MAX_N = 200*1000; /* at most 200*10^3 packets after enc */ +const INT32 LDPC_DEFAULT_K = 20*1000; /* default: 20*10^3 packets */ +const INT32 LDPC_DEFAULT_N = 40*1000; /* default: 40*10^3 packets */ +#endif +#endif /* FEC */ + + +/* + * default transmission profile + * choose one (can be overided with mcl_ctl anyway) + * + * WARNING1: using a DFLT_TX_PROFILE overrides the actual max_tx_level, + * datagram_size, and tx_rate... (see mcl_tx_prof.c) + * WARNING2: a change of the default datagram size must be done both at + * source and receivers. + */ +/*#define DFLT_TX_PROFILE MCL_TX_PROFILE_LOW_RATE_INTERNET*/ +#define DFLT_TX_PROFILE MCL_TX_PROFILE_MID_RATE_INTERNET +/*#define DFLT_TX_PROFILE MCL_TX_PROFILE_HIGH_SPEED_LAN*/ + + +/* + * max number of transmission layers + * max number of multicast groups + */ +#define MAX_NB_TX_LAYERS 20 /* max nb of layers */ +#define MAX_MC_GROUP MAX_NB_TX_LAYERS + + +/* + * mtu max tx unit as defined by the physical layer (it does not + * consider IP and above headers). Be careful, if you know + * that tunneling is used, reduce this size! + * payload data payload of an ALC packet (if any) + * header ALC/LCT header only + * datagram includes payload plus ALC/LCT header. + * This is the Protocol Data Unit given to UDP + * ip_datagram includes datagram plus UDP/IP headers + * + * WARNING: changes of these sizes must be done both at source and receivers... + */ +//const INT32 DFLT_MTU = 576; +const INT32 DFLT_MTU = 1400; +const INT32 MAX_ETHERNET_MTU = 1500; + +const INT32 UDP_IPv4_HEADER_SIZE = (8 + 20); // in case of IPv4 +const INT32 UDP_IPv6_HEADER_SIZE = (8 + 40); // in case of IPv6 + +// ALC/LCT headers cannot be smaller in any case +const INT32 MIN_ALC_HEADER_SIZE = 8; +// ALC/LCT headers cannot be larger +// 4(fixed hdr) + 4(CCI) + 4(TSI) + 4(TOI) + 24(our FTI) + 8(No NEW ADU) +// + 8(FPI) + 4 (FDT/MODT) +// This maximum header size is really MCL specific, since it takes into +// account features not supported by MCL (e.g. CCI of more than 32bits), +// and additional fields required by MCL (FTI for FEC Enc ID 140, No NEW ADU). +const INT32 MAX_ALC_HEADER_SIZE = 60; + +#ifdef INET6 +// if compiled with IPv6 support, then be conservative: reserve room +// for IPv6 headers... +const INT32 MAX_DATAGRAM_SIZE = (DFLT_MTU - UDP_IPv6_HEADER_SIZE); +#else +const INT32 MAX_DATAGRAM_SIZE = (DFLT_MTU - UDP_IPv4_HEADER_SIZE); +#endif +const INT32 DFLT_DATAGRAM_SIZE = MAX_DATAGRAM_SIZE; + +const INT32 MAX_PAYLOAD_SIZE = (MAX_DATAGRAM_SIZE - + MAX_ALC_HEADER_SIZE); +const INT32 DFLT_PAYLOAD_SIZE = MAX_PAYLOAD_SIZE; + + +/* + * period of the main timer; used to trigger all the periodic processings + * (congestion control timers, data transmissions, etc.) + */ +/* + * this value (in microseconds) determines the internal MCL clock granularity. + * It is the sleep duration between two consecutive virtual time ticks. + * All other timers (see below) are multiples of this period! + * (eg. MCL_TX_PERIOD can be set to 2*MCL_TIMER_PERIOD for half the frequency) + * + * The MCL_PERIODIC_TIMER_PERIOD is set in common/mcl_periodic_timer.h + * and can be changed there. + */ +#define MCL_TIMER_PERIOD MCL_PERIODIC_TIMER_PERIOD + +/* + * period in microseconds between two calls to the RLC timer func (receiver). + * NB: must be a multiple of MCL_TIMER_PERIOD! + */ +#define MCL_RLC_RX_PERIOD (10 * MCL_TIMER_PERIOD) + + +/* + * default polling period... + * This is a compromize, not too high to limit resource consumption, + * not too low to have a good reactivity. + * (using MCL_TIMER_PERIOD is nice as it defines the max rate at which new + * packets are sent and thus events can take place) + */ +#define DFLT_POLLING_PERIOD ((unsigned long)4 * MCL_TIMER_PERIOD) + + +#ifdef METAOBJECT_USED +/* + * polling period in the case Metaobjects are used + * it is a multiple of DFLT_POLLING_PERIOD since + * searching decoded obkects in a metaobject uses + * quite a lot CPU + */ +#define MODT_POLLING_PERIOD ((unsigned long)25 * DFLT_POLLING_PERIOD) +#endif + +/* + * send important data every MCL_IMPORTANT_DATA_FREQUENCY (microseconds) + * Take care: amount of important data may become not important enough if + * we have high transmission rates and/or only one tx layer. + */ +#define IMPORTANT_DATA_FREQUENCY 250000.0 //1000000.0 = 1 second + +/* + * Do you want to simulate random bursty packet losses? + * (i.e. the source will randomly forget to send some bursts of packets) + * Usually NO... + */ +/* #define SIMUL_LOSSES */ + +#ifdef SIMUL_LOSSES +/* + * Should losses be independant of layer number (ie be constant) or not ? + */ +//#define CONSTANT_LOSS_RATIO +/* + * number of (simulated) losses in % when the previous packet was OK + */ +#define P_LOSS_WHEN_OK 0.1 +//#define P_LOSS_WHEN_OK 0.5 +//#define P_LOSS_WHEN_OK 1 +/* + * number of (simulated) losses in % when the previous packet was LOST + */ +#define P_LOSS_WHEN_LOSSES 10 +//#define P_LOSS_WHEN_LOSSES 75 +#endif /* SIMUL_LOSSES */ + + +#ifdef SOLARIS +/* + * Do you want to collect system information? + * IMPORTANT: Requires to edit mcl_stats.c!!! Change the login name and + * tool name (in the grep) + * Ok, that's a bit ugly but it is so simple... + * NB: Only works on solaris today! + */ +/*#define GET_SYSINFO*/ + +#ifdef GET_SYSINFO +#define MCL_SYSINFO_PERIOD (3 * MCL_TIMER_PERIOD) +#endif /* GET_SYSINFO */ +#endif /* SOLARIS */ + + +/* + * default ttl used for multicast tx + */ +#define TTL 1 + + +/* + * create temporary file in this dir + * (e.g. used by the vtmem service) + */ +#ifdef WIN32 +#define MCL_DEFAULT_TMP_DIR_NAME "" +#else /* UNIX */ +#define MCL_DEFAULT_TMP_DIR_NAME "/tmp/" +#endif /* UNIX */ + + +/* + * do you want that all traces (out and error) are sent to a dedicated + * file in the temporary directory defined above or to the stdout and + * stderr standard output? + */ +/*#define STDOUT_TO_FILE*/ + +/* ODT parameters */ +#define ODT_VERSION 1 +#define MOID_LEN 2 +#define NB_OF_OBJECTS_LEN 2 +#define OBJECTS_LEN_LEN 4 + +#endif /* } MCL_PROFILE_H */ diff --git a/src/alc/mcl_proto.h b/src/alc/mcl_proto.h new file mode 100644 index 0000000..ed2a34d --- /dev/null +++ b/src/alc/mcl_proto.h @@ -0,0 +1,144 @@ +/* $Id: mcl_proto.h,v 1.21 2005/03/18 12:06:18 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_PROTO_H /* { */ +#define MCL_PROTO_H + +/****** public function prototypes ******/ + + +/* + * mcl_layer.c + */ +#ifdef SVSOA_RECV +extern int mcl_init_layer_nb (class mcl_cb *mclcb, INT32 nb_level); +#else +extern int mcl_init_layer_nb (class mcl_cb *mclcb); +#endif +extern mcl_error_status mcl_init_layer_sockets (mcl_cb *mclcb); +//extern int mcl_get_nb_fec_layers (class mcl_cb *mclcb, INT32 k); +extern int mcl_add_layer (class mcl_cb *mclcb, INT32 layer); +extern int mcl_drop_layer (class mcl_cb *mclcb, INT32 layer, int check); +extern int mcl_drop_this_layer (class mcl_cb *mclcb, INT32 layer); +extern int mcl_free_all_layers (class mcl_cb *const mclcb); + + +/* + * mcl_sched.c + */ +extern void UpdateTxPlanning (class mcl_cb *mclcb, adu_t *adu_start, + adu_t *adu_end); +extern void AnticipTx_UpdateTxPlanning (class mcl_cb *mclcb, adu_t *adu); + + +/* + * mcl_rx.c + */ +extern void* mcl_rx_thread (void *arg); +extern void mcl_process_pkt (class mcl_cb* mclcb, mcl_rx_pkt *pkt, + mcl_addr *saddr, INT32 layer); +extern int mcl_process_sig (mcl_cb *mclcb, int type, + hdr_infos_t *hdr_infos, + mcl_addr *saddr); + + +/* + * mcl_sig.c + */ +extern int SendNONEWADU (class mcl_cb *mclcb, INT32 max_adu); +extern int SendCLOSE (class mcl_cb *mclcb); +extern int AddSigToTab (class mcl_cb *mclcb, sig_tab_t *new_sig); +extern int RemSigFromTab (class mcl_cb *mclcb, INT32 level, + INT32 type, INT32 ext_type); +extern void CopySigReset (class mcl_cb *mclcb); +extern int CanCopyMoreSig (class mcl_cb *mclcb, INT32 level); +extern int CopySigToLCTinfos(class mcl_cb *mclcb, INT32 level, + hdr_infos_t *hdr_infos, + INT32 len); +extern int CleanupSigTab (class mcl_cb *mclcb); +extern void mcl_sig_close (class mcl_cb *mclcb); + + +/* + * mcl_network.c + */ +extern int mcl_send_pkt (class mcl_cb *mclcb,INT32 level, + du_t *du, adu_t *adu); +extern void mcl_recv_pkt (class mcl_cb *mclcb); + + +/* + * mcl_du.c + */ +extern du_t* CreateDU (class mcl_cb *mclcb); +extern du_t* LastDU (class mcl_cb *mclcb, du_t *list); +extern int InsertDU (class mcl_cb *mclcb, du_t *du, + du_t **list); +extern int mcl_rx_enough_du (class mcl_cb *mclcb, block_t *blk); + + +/* + * mcl_adu.c + */ +extern adu_t* mcl_create_adu (class mcl_cb *mclcb); +extern void mcl_insert_adu (class mcl_cb *mclcb, adu_t *adu, + adu_t **list); +extern adu_t* mcl_find_adu (class mcl_cb *mclcb, UINT32 seq, + INT32 FDTinstanceID, adu_t *list); +extern void mcl_remove_adu (class mcl_cb *mclcb, adu_t *adu, + adu_t **list); +extern int mcl_rx_new_completed_adu (class mcl_cb *mclcb, adu_t *adu); +extern int mcl_rx_all_adu_completed (class mcl_cb *mclcb, adu_t *list); +extern block_t* FindBlock (class mcl_cb *mclcb, UINT32 seq, + block_t *list, adu_t *adu); +extern int mcl_get_highest_toi (mcl_cb *mclcb, adu_t *list); +extern void mcl_tx_segment_adu (class mcl_cb *mclcb, adu_t *adu); +extern void mcl_tx_free_this_adu (class mcl_cb *mclcb, adu_t *adu); +extern void mcl_rx_free_this_adu (class mcl_cb *mclcb, adu_t *adu); +//extern void mcl_free_all_adu (class mcl_cb *mclcb); + + +/* + * mcl_tx_prof.c + */ +extern int mcl_set_tx_profile (class mcl_cb *mclcb, + INT32 profile); +extern mcl_error_status mcl_print_tx_profile (mcl_cb *mclcb); + + +#ifdef VIRTUAL_TX_MEM +/* + * mcl_vtmem.c + */ +extern int mcl_vtm_can_store_in_vtm(class mcl_cb *mclcb, INT32 len); +extern int mcl_vtm_store_data (class mcl_cb *mclcb, adu_t *adu, + du_t *du, char *data, INT32 len, + INT32 padded_len); +extern void mcl_vtm_register_du (class mcl_cb *mclcb, du_t *du, + UINT32 off); +extern void mcl_vtm_register_in_ptm (class mcl_cb *mclcb, adu_t *adu, + du_t *du, INT32 len); +extern char* mcl_vtm_get_data (class mcl_cb *mclcb, du_t *du); +extern int mcl_vtm_close (class mcl_cb *mclcb); +#endif /* VIRTUAL_TX_MEM */ + + +#endif /* } MCL_PROTO_H */ diff --git a/src/alc/mcl_rlc.cpp b/src/alc/mcl_rlc.cpp new file mode 100644 index 0000000..cabacbf --- /dev/null +++ b/src/alc/mcl_rlc.cpp @@ -0,0 +1,864 @@ +/* $Id: mcl_rlc.cpp,v 1.10 2005/01/11 13:12:32 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * This file contains implementations for RLC congestion control. + */ +#include "mcl_includes.h" + +#ifdef RLC + +/* + * Definition of global RLC variables + */ +UINT32 mcl_rlc_rx_period = MCL_RLC_RX_PERIOD; + + +/* + * Local private function prototypes + */ +static INT32 rlc_SP_spacing (rlccb_t *rlccb, INT32 layer); +static INT32 CheckSequence (mcl_cb *mclcb, UINT8 layer, UINT16 seqid); +static void RxProcessSP (mcl_cb *mclcb, rlccb_t *rlccb, UINT8 layer); +static INT32 AddLate (mcl_cb *mclcb, INT32 layer, INT32 nseq); +static INT32 RemoveLate (mcl_cb *mclcb, INT32 layer, INT32 nseq); +static INT32 UpdateLateList (mcl_cb *mclcb); +static INT32 AddLost (mcl_cb *mclcb); +static INT32 UpdateLossList (mcl_cb *mclcb); +static void FreeLists (mcl_cb *mclcb); + + +/****** PUBLIC FUNCTIONS ******************************************************/ + + +/** + * Initializes the RLC congestion control mechanism for a given session. + * => See header file for more informations. + */ +void +rlc_init_session (mcl_cb *mclcb) +{ + INT32 i; + rlccb_t *rlccb; + + TRACELVL( 5, (mcl_stdout, "-> RLC:rlc_init_session: mclcb=x%x\n", (int) mclcb)) + + rlccb = &(mclcb->rlccb); + memset((void *)rlccb, 0, sizeof(rlccb_t)); + + rlccb->rlc_sp_cycle = RLC_SP_CYCLE; + rlccb->rlc_pkt_timeout = RLC_PKT_TIMEOUT; + rlccb->rlc_deaf_period = RLC_DEAF_PERIOD; + rlccb->rlc_loss_accepted = RLC_LOSS_ACCEPTED; + rlccb->rlc_late_accepted = RLC_LATE_ACCEPTED; + rlccb->rlc_loss_limit = RLC_LOSS_LIMIT; + rlccb->rlc_loss_timeout = RLC_LOSS_TIMEOUT; + /* do it now (and later on after the FIRST packet tx) */ + /*rlc_reset_sp(mclcb);*/ + for (i = 0 ; i < MAX_NB_TX_LAYERS; i++) { + rlccb->rx_first_pkt[i] = 1; + /* + * init first_sp to 0 to start normally, and + * with 1 for a really slow start (i.e. the first SP of + * each layer will be ignored) + */ + /*rlccb->rx_first_sp[i] = 1;*/ + rlccb->rx_first_sp[i] = 0; + /* used to test overflows */ + /* rlccb->tx_layers_seq[i]=65500; */ + } + TRACELVL(5, (mcl_stdout, "<- RLC:rlc_init_session\n")) +} + + +/** + * Reset all SP variables at the sending side. + * => See header file for more informations. + */ +void +rlc_reset_tx_sp (mcl_cb *mclcb) +{ + INT32 i; + rlccb_t *rlccb = &(mclcb->rlccb); + + for (i = 0 ; i < MAX_NB_TX_LAYERS; i++) { + rlccb->tx_next_sp[i] = rlc_SP_spacing(rlccb, i); + TRACELVL(3, (mcl_stdout, + " RLC: rlc_reset_tx_sp: layer=%d, SP_spacing=%d, next_SP=%d\n", + i, rlccb->tx_next_sp[i] - mcl_time_count, rlccb->tx_next_sp[i])) + } +} + + +/** + * Must be called when ending a session. + * => See header file for more informations. + */ +void +rlc_end_session (mcl_cb *mclcb) +{ + TRACELVL(5, (mcl_stdout, "-> RLC: rlc_end_session\n")) + FreeLists(mclcb); + TRACELVL(5, (mcl_stdout, "<- RLC: rlc_end_session\n")) +} + + +/** + * Fill the RLC header for each packet to send. + * => See header file for more informations. + */ +INT32 +rlc_tx_fill_header (mcl_cb *mclcb, rlc_hdr_t *hdr_buff, UINT8 layer) +{ + UINT16 hdr_seqid; + rlccb_t *rlccb; + + ASSERT(mclcb); + rlccb = &(mclcb->rlccb); + TRACELVL(5, (mcl_stdout, + "-> RLC: rlc_fill_header: mclcb=x%x, layer=%d\n", + (int) mclcb, layer)) + ASSERT(layer < MAX_NB_TX_LAYERS && layer < mclcb->nb_layers) + hdr_seqid = rlccb->tx_layers_seq[layer]; + (rlccb->tx_layers_seq[layer])++; + + ASSERT(hdr_buff!=NULL) + hdr_buff->rlc_reserved = 0x55; /* unused: rlc_reserved=1010101 */ + hdr_buff->rlc_layer = layer; + hdr_buff->rlc_seqid = htons(hdr_seqid); + + /* no SP if we are in single_layer mode */ + if(!mclcb->single_layer_mode && rlccb->tx_next_sp[layer] <= mcl_time_count) { + /* OK this is a new SP for this layer */ + hdr_buff->rlc_sp = 1; + /* calculate when next SP will occur */ + rlccb->tx_next_sp[layer] = rlc_SP_spacing(rlccb, layer); + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tSP_all %d\n", + time.tv_sec, time.tv_usec, layer)) + } + TRACELVL(3, (mcl_stdout, + " RLC hdr info: layer=%d, seq=%d, SP=yes, next_SP=%d\n", + layer, hdr_seqid, rlccb->tx_next_sp[layer])) +#if 0 + if (layer+1 < MAX_NB_TX_LAYERS && + mclcb->txlay_tab[layer+1].wait_sp == 1) { + /* start tx on upper layers (if not already done) */ + /* nb: do not start before the first packet tx */ + mclcb->txlay_tab[layer+1].wait_sp = 0; + /* nb: wait_after_sp_count already initialized */ + } +#endif + } else { /* not a SP... */ + hdr_buff->rlc_sp = 0; + TRACELVL(3, (mcl_stdout, " RLC hdr info: layer=%d, seq=%d, SP=no\n", + layer, hdr_seqid)) + } + + TRACELVL(5, (mcl_stdout, "<- RLC: rlc_fill_header: ok\n")) + return MCL_OK; +} + + +/** + * Analyse the packet's RLC header. + * => See header file for more informations. + */ +INT32 +rlc_rx_analyze_packet (mcl_cb *mclcb, rlc_hdr_t *hdr_buff ) +{ + UINT8 hdr_layer; + UINT16 hdr_seqid; + char hdr_sp; + rlccb_t *rlccb; + + ASSERT(hdr_buff!=NULL) + TRACELVL(5, (mcl_stdout, "-> RLC: rlc_rx_analyze_packet\n")) + + ASSERT(mclcb); + rlccb = &(mclcb->rlccb); + + hdr_seqid = ntohs(hdr_buff->rlc_seqid); + hdr_layer = hdr_buff->rlc_layer; + hdr_sp = hdr_buff->rlc_sp; + + if(hdr_buff->rlc_reserved != 0x55) { + /* Unrecognized/corrupt RLC header, so ignore... */ + TRACELVL(5, (mcl_stdout, "<- RLC: rlc_rx_analyze_packet (CORRUPT_HDR)\n")) + return ERR_CORRUPT_HDR; + } + if(hdr_layer >= mclcb->nb_layers) { + /* Bad layer, should not receive on it, so ignore... */ + TRACELVL(5, (mcl_stdout, "<- RLC: rlc_rx_analyze_packet (BAD_LAYER)\n")) + return ERR_BAD_LAYER; + } + + UpdateLossList(mclcb); + + if ( rlccb->rx_deaf_wait ) + { + TRACELVL(3, (mcl_stdout, "rlc_rx_analyze_packet: in DEAF!!! rlccb->rx_deaf_wait=%d\n", + rlccb->rx_deaf_wait)) + /* Do nothing more as we're in deaf period */ + rlccb->rx_wait_for[hdr_layer]= hdr_seqid + 1; + goto end; + } + + if(rlccb->rx_first_pkt[hdr_layer]) + { + /* First packet on this layer... */ + rlccb->rx_wait_for[hdr_layer] = hdr_seqid + 1; + rlccb->rx_first_pkt[hdr_layer] = 0; + /* continue as this pkt may contain an SP */ + } else { + /* check if some pkts have been lost or not */ + CheckSequence(mclcb, hdr_layer, hdr_seqid); + } + + if(hdr_sp) + { + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tSP_all %d\n", + time.tv_sec, time.tv_usec, hdr_layer)) + } + if(hdr_layer == mclcb->nb_layers-1) + { + /* This is a Synchronisation Point */ + if(rlccb->rx_first_sp[hdr_layer] == 1) { + /* skip 1st SP, especially after deaf-period */ + rlccb->rx_first_sp[hdr_layer] = 0; + } else { + RxProcessSP(mclcb, rlccb, hdr_layer); + } + } + } + +end: + TRACELVL(5, (mcl_stdout, "<- RLC: rlc_rx_analyze_packet (ok)\n")) + return hdr_layer; +} + + +/** + * Timer function, called periodically by the receiver. + * => See header file for more informations. + */ +mcl_error_status +rlc_rx_timer (mcl_cb *mclcb) +{ + rlccb_t *rlccb = &(mclcb->rlccb); + + TRACELVL(5, (mcl_stdout, "-> RLC: rlc_rx_timer mclcb=x%x\n",(int)mclcb)) + if ( rlccb->rx_deaf_wait > 0 ) { + (rlccb->rx_deaf_wait)--; + TRACELVL(3, (mcl_stdout, "rlc_rx_timer: new rlccb->rx_deaf_wait=%d\n", + rlccb->rx_deaf_wait)) + if (rlccb->rx_deaf_wait == 0) { + TRACELVL(3, (mcl_stdout, " RLC: End of Deaf Period\n")) + /* + * skip next SP to be sure to wait for a complete + * SP period + */ + /*for (i=0; irx_first_sp[i] = 1;*/ + rlccb->rx_first_sp[mclcb->nb_layers-1] = 1; + + if (mclcb->get_verbosity() == 2 ) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT(( stdout, "\n%ld.%06ld\tend_deaf\n", + time.tv_sec, time.tv_usec)) + } + } + } else { + UpdateLateList(mclcb); + } + + TRACELVL(5, (mcl_stdout, "<- RLC: rlc_rx_timer (ok)\n")) + return MCL_OK; +} + + +/** + * Used to set various RLC options and parameters. + * => See header file for more informations. + */ +mcl_error_status +rlc_ctl (mcl_cb *mclcb, INT32 optname, void *optvalue, INT32 optlen) +{ + rlccb_t *rlccb = &(mclcb->rlccb); + + TRACELVL(5, (mcl_stdout, "-> RLC: rcl_ctl: optname=%d, optvalue=x%x, optlen=%d\n", + optname, (int)optvalue, optlen)) + + switch (optname) { + case RLC_OPT_SP_CYCLE: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "rlc_ctl ERROR RLC_OPT_SP_CYCLE: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < 0 ) { + PRINT_ERR((mcl_stderr,"rlc_ctl ERROR: RLC_OPT_SP_CYCLE must be positive (got %d)\n",(*(int*)optvalue))) + goto error; + } + rlccb->rlc_sp_cycle = *(int*)optvalue; + break; + + case RLC_OPT_PKT_TIMEOUT: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR(( stderr, "rlc_ctl ERROR RLC_OPT_PKT_TIMEOUT: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < 0 ) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR: RLC_OPT_PKT_TIMEOUT must be positive (got %d)\n",(*(int*)optvalue))) + goto error; + } + rlccb->rlc_pkt_timeout = *(int*)optvalue; + break; + + case RLC_OPT_DEAF_PERIOD: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR(( stderr, "rlc_ctl ERROR RLC_OPT_DEAF_PERIOD: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < 0 ) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR: RLC_OPT_DEAF_PERIOD must be positive (got %d)\n",(*(int*)optvalue))) + goto error; + } + rlccb->rlc_deaf_period = *(int*)optvalue; + break; + + case RLC_OPT_LOSS_ACCEPTED: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR RLC_OPT_LOSS_ACCEPTED: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < 0 ) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR: RLC_OPT_LOSS_ACCEPTED must be positive (got %d)\n",(*(int*)optvalue))) + goto error; + } + rlccb->rlc_loss_accepted = *(int*)optvalue; + break; + + case RLC_OPT_LATE_ACCEPTED: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR RLC_OPT_LATE_ACCEPTED: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < 0 ) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR: RLC_OPT_LATE_ACCEPTED must be positive (got %d)\n",(*(int*)optvalue))) + goto error; + } + rlccb->rlc_late_accepted = *(int*)optvalue; + break; + + case RLC_OPT_LOSS_LIMIT: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR RLC_OPT_LOSS_LIMIT: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < 0 ) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR: RLC_OPT_LOSS_LIMIT must be positive (got %d)\n",(*(int*)optvalue))) + goto error; + } + rlccb->rlc_loss_limit = *(int*)optvalue; + break; + + case RLC_OPT_LOSS_TIMEOUT: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR RLC_OPT_LOSS_TIMEOUT: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < 0 ) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR: RLC_OPT_LOSS_TIMEOUT must be positive (got %d)\n",(*(int*)optvalue))) + goto error; + } + rlccb->rlc_loss_timeout = *(int*)optvalue; + break; + + case RLC_OPT_AGGRESSIVE_CC: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR RLC_OPT_AGGRESSIVE_CC: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) != 0 && (*(int*)optvalue) != 1) { + PRINT_ERR((mcl_stderr, "rlc_ctl ERROR: RLC_OPT_AGGRESSIVE_CC must be 0 or 1 (got %d)\n",(*(int*)optvalue))) + goto error; + } + rlccb->rlc_lan_cc = *(int*)optvalue; + if (rlccb->rlc_lan_cc) { + /* + * if we indeed have a LAN congestion control profile, + * then adapt various parameters: SP spacing, death + * period... + */ + /* nb: SP spacing will be done in rlc_SP_spacing() + * function */ + rlccb->rlc_deaf_period = RLC_LAN_DEAF_PERIOD; + rlccb->rlc_late_accepted = RLC_LAN_LATE_ACCEPTED; + rlccb->rlc_loss_accepted = RLC_LAN_LOSS_ACCEPTED; + rlccb->rlc_loss_limit = RLC_LAN_LOSS_LIMIT; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: RLC_OPT_AGGRESSIVE_CC (%d)\n", rlccb->rlc_lan_cc)) + break; + + default: + PRINT_ERR((mcl_stderr, + "rlc_ctl ERROR: Unknown option %d\n", optname)) + goto error; + } + + TRACELVL(5, (mcl_stdout, "<- RLC: rlc_ctl (ok)\n")) + return MCL_OK; + +error: + TRACELVL(5, (mcl_stdout, "<- RLC: rlc_ctl (Failure)\n")) + return MCL_ERROR; +} + + +/****** PRIVATE FUNCTIONS *****************************************************/ + + +/** + * Calculate the SP spacing. + * @return The time (in the mcl_time_count timeline) when + * next SP will occur. + */ +static int +rlc_SP_spacing (rlccb_t *rlccb, + INT32 layer) +{ + INT32 spacing; + + if (rlccb->rlc_lan_cc) { + /* aggressive RLC setup for LAN only tx */ + if (layer <= 1) + spacing = (int)(rlccb->rlc_sp_cycle / MCL_TIMER_PERIOD) * (layer + 1); + else + spacing = (int)(1000000 / MCL_TIMER_PERIOD); /* 1s */ + } else { + /* use a linear spacing of SPs on the layers */ + /*spacing = (int)(rlccb->rlc_sp_cycle / MCL_TIMER_PERIOD)*/ + /* * (layer + 1);*/ + /* use expon. spacing of SPs on the layers with upper bound */ + spacing = (int)(rlccb->rlc_sp_cycle / MCL_TIMER_PERIOD) + * ((1 << (layer+1))-1); + } + return(mcl_time_count + spacing); +} + + +/** + * Used by a receiver to detect packet losses/delays and take appropriate + * measures. + * @param mclcb session Control Block + * @return Completion status (MCL_OK or MCL_ERROR) + */ +static INT32 +CheckSequence (mcl_cb *mclcb, UINT8 layer, UINT16 seqid) +{ + rlccb_t *rlccb; + UINT16 Delta1, Delta2 = 0; + UINT16 i, late_limit; + + ASSERT(mclcb); + TRACELVL(5, (mcl_stdout, "-> RLC: CheckSequence\n")) + rlccb = &(mclcb->rlccb); + if( rlccb->rx_wait_for[layer] == seqid ) + { /* This is the packet we're waiting for, let's go on! */ + (rlccb->rx_wait_for[layer])++; + TRACELVL(5, (mcl_stdout, "<- RLC: CheckSequence (good seq)\n")) + return MCL_OK; + } + + /* This is not the one we're waiting for... */ + if( rlccb->rx_wait_for[layer] < seqid ) + { + Delta1 = seqid - rlccb->rx_wait_for[layer]; + Delta2 = 65535 - Delta1; + if ( Delta1 < Delta2 ) { + /* Some packet(s) are missing */ + /* eg. wait seq 1512 and get 1513, so 1512 is missing */ + late_limit=RLC_MAX_LATES; + for ( i = rlccb->rx_wait_for[layer]; i < seqid; i++) + { + AddLate(mclcb, layer, i); + late_limit--; + if(late_limit <= 0 ) + { + TRACELVL(3, (mcl_stdout, + " RLC Warning*** Max number of LATE packets reached\n")) + break; + } + } + rlccb->rx_wait_for[layer] = seqid +1; + } + else { + /* Late arrival packet (uint16 overflow) */ + /* eg. we're waiting seq 4 and we get seq 65532 */ + RemoveLate(mclcb, layer, seqid); + } + } + else /* rx_wait_for > rlc_seqid */ + { + Delta1 = rlccb->rx_wait_for[layer] - seqid; + Delta2 = 65535 - Delta1; + if ( Delta1 < Delta2 ) + {/* Late arrival packet */ + /* ie: we're waiting seq 501 and we get seq 498 */ + RemoveLate(mclcb, layer, seqid); + } + else { + /* Some packet(s) are missing (uint16 overflow) */ + /* ie: waiting seq 65531 and get seq 3 */ + late_limit = RLC_MAX_LATES; + for (i = rlccb->rx_wait_for[layer]; i != (seqid-1); i++) + { + AddLate(mclcb, layer, i); + late_limit--; + if(late_limit == 0 ) + { + TRACELVL(3, (mcl_stdout, + " RLC Warning*** Max number of LATE packets reached\n")) + break; + } + } + rlccb->rx_wait_for[layer] = seqid +1; + } + } + + TRACELVL(5, (mcl_stdout, "<- RLC: CheckSequence (seq broken)\n")) + return MCL_ERROR; +} + + + +/** + * + * @param mclcb session Control Block + */ +static void +RxProcessSP (mcl_cb *mclcb, rlccb_t *rlccb, UINT8 layer) +{ + TRACELVL(5, (mcl_stdout, "-> RLC: RxProcessSP\n")) + TRACELVL(3, (mcl_stdout, " RLC: Sync Point (toplevel=%d)\n", layer)) + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tSP_received %d\n", + time.tv_sec, time.tv_usec, layer)) + } + + if (rlccb->rx_nblost_since_sp <= rlccb->rlc_loss_accepted + && rlccb->rx_nblate_since_sp <= rlccb->rlc_late_accepted) + { + mcl_add_layer(mclcb, MCL_HIGHEST_LAYER); + /*rlccb->rx_first_sp[mclcb->nb_layers-1] = 1;*/ + TRACELVL(2, (mcl_stdout, " RLC: add a new layer, now receiving from %d layers\n", mclcb->nb_layers)) + } + rlccb->rx_nblost_since_sp = 0; + rlccb->rx_nblate_since_sp = 0; + + TRACELVL(5, (mcl_stdout, "<- RLC: RxProcessSP\n")) +} + + +/** + * A packet is late, remember it. + * @param mclcb session Control Block + * @return Completion status (MCL_OK or MCL_ERROR) + */ +static INT32 +AddLate (mcl_cb *mclcb, INT32 layer, INT32 nseq) +{ + rlccb_t *rlccb; + late_list_t *new_missing; + + TRACELVL(5, (mcl_stdout, "-> RLC: AddLate\n")) + ASSERT(mclcb && (layer <= mclcb->nb_layers)); + rlccb = &(mclcb->rlccb); + + if( !( new_missing = (late_list_t *)malloc(sizeof(late_list_t))) ) { + PRINT_ERR((mcl_stderr, "AddLate: no memory")) + mcl_exit(-1); + } + new_missing->seq_num = nseq; + ASSERT(mcl_rlc_rx_period!=0) + new_missing->ttw = rlccb->rlc_pkt_timeout / mcl_rlc_rx_period; + new_missing->next = rlccb->rx_missing[layer].next; + rlccb->rx_missing[layer].next = new_missing; + (rlccb->rx_nblate)++; + (rlccb->rx_nblate_since_sp)++; + + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tlate_detected %d %d %d\n", + time.tv_sec, time.tv_usec, layer, nseq, rlccb->rx_nblate)) + } + /* update stats: assume a late pkt is lost (corrected later if req.) */ + mclcb->stats.rx_lost_pkts++; + mclcb->stats.rx_lost_per_lvl[layer]++; + TRACELVL(3, (mcl_stdout, " RLC: pkt %d of layer %d late, total %d late\n", + nseq, layer, rlccb->rx_nblate)) + TRACELVL(5, (mcl_stdout, "<- RLC: AddLate: ok\n")) + return MCL_OK; +} + + +/** + * We finally received the delayed packet. + * @param mclcb session Control Block + * @return Completion status (MCL_OK or MCL_ERROR) + */ +static INT32 +RemoveLate (mcl_cb *mclcb, INT32 layer, INT32 nseq) +{ + rlccb_t *rlccb; + late_list_t *prev, *current; + TRACELVL(5, (mcl_stdout, "-> RLC: RemoveLate seq=%d on layer %d\n", nseq, layer)) + + ASSERT(mclcb && (layer<=mclcb->nb_layers)); + rlccb = &(mclcb->rlccb); + prev = &(rlccb->rx_missing[layer]); + current = prev->next;; + + while ( current != NULL && current->seq_num != nseq ) { + prev = current; + current = current->next; + } + if(current == NULL) { + TRACELVL(5, (mcl_stdout, "<- RLC: RemoveLate (Missing)\n")) + return MCL_ERROR; + } + else { + prev->next = current->next; + free(current); + (rlccb->rx_nblate)--; + (rlccb->rx_nblate_since_sp)--; + } + /* correct stats... */ + mclcb->stats.rx_lost_pkts--; + mclcb->stats.rx_lost_per_lvl[layer]--; + TRACELVL(5, (mcl_stdout, "<- RLC: RemoveLate (Removed)\n")) + return MCL_OK; +} + + +/** + * + * @param mclcb session Control Block + * @return Completion status (MCL_OK or MCL_ERROR) + */ +static INT32 +UpdateLateList (mcl_cb *mclcb) +{ + INT32 layer; + rlccb_t *rlccb; + late_list_t *prev, *current; + + TRACELVL(5, (mcl_stdout, "-> RLC: UpdateLateList\n")) + ASSERT(mclcb); + rlccb = &(mclcb->rlccb); + +#ifdef DEBUG + if( rlccb->rx_nblate > 0 ) { + TRACELVL(3, (mcl_stdout, " RLC: packets late:\n")) + } +#endif + + for ( layer = 0; layer < mclcb->nb_layers; layer++) + { + prev = &(rlccb->rx_missing[layer]); + current = prev->next; + + while ( current != NULL) + { + ASSERT( current->ttw !=0 ) + TRACELVL(3, (mcl_stdout, "\t layer=%d nseq=%d ttw=%d\n", + layer, current->seq_num, current->ttw)) + + if((--(current->ttw)) == 0) { + /* this one is lost! */ + INT32 nseq = current->seq_num; + prev->next = current->next; + free(current); + (rlccb->rx_nblate)--; + (rlccb->rx_nblate_since_sp)--; + + UpdateLossList(mclcb); + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tloss_detected %d %d %d\n", + time.tv_sec, time.tv_usec, + layer, nseq, rlccb->rx_nblost+1)) + } + TRACELVL(3, (mcl_stdout, " RLC: pkt %d of layer %d lost! total: %d lost\n", + nseq, layer, rlccb->rx_nblost+1)) + if( AddLost(mclcb) == TOO_MANY_LOSSES ) + goto end; + } + else prev = current; + current = prev->next; + } + } + +end: + TRACELVL(5, (mcl_stdout, "<- RLC: UpdateLateList (ok)\n")) + return MCL_OK; + +} + + +/** + * + * @param mclcb session Control Block + */ +static INT32 +AddLost (mcl_cb *mclcb) +{ + rlccb_t *rlccb; + lost_list_t *new_lost; + + TRACELVL(5, (mcl_stdout, "-> RLC: AddLost\n")) + ASSERT(mclcb); + rlccb = &(mclcb->rlccb); + rlccb->rx_nblost ++; + rlccb->rx_nblost_since_sp ++; + + if ( rlccb->rx_nblost >= rlccb->rlc_loss_limit ) { + /* too many losses... drop a layer! */ + if (mcl_drop_layer(mclcb, MCL_HIGHEST_LAYER, MCL_DO_IT ) < 0) { + /* error, cannot drop layer */ + TRACELVL(5, (mcl_stdout, "<- RLC: AddLost: cant drop layer, ignore\n")) + return MCL_OK; + } + TRACELVL(2, (mcl_stdout, " RLC: congestion, drop a layer, now receiving from %d layers\n", + mclcb->nb_layers)) + + /* initial state for futur potential use of this layer*/ + rlccb->rx_first_pkt[mclcb->nb_layers]=1; + + /* Clean up late and lost lists... */ + FreeLists(mclcb); + /* entering the deaf period... */ + ASSERT(mcl_rlc_rx_period!=0) + rlccb->rx_deaf_wait = rlccb->rlc_deaf_period/mcl_rlc_rx_period; + TRACELVL(3, (mcl_stdout, "AddLost: LOSS, rlccb->rx_deaf_wait=%d\n", + rlccb->rx_deaf_wait)) + TRACELVL(5, (mcl_stdout, "<- RLC: AddLost: too many losses, layer dropped\n")) + return TOO_MANY_LOSSES; + } + + if( !( new_lost = (lost_list_t *)malloc(sizeof(lost_list_t)))) { + PRINT_ERR((mcl_stderr, "AddLost: no memory")) + mcl_exit(-1); + } + new_lost->pkt_remaining = rlccb->rlc_loss_timeout; + new_lost->next = rlccb->rx_lost.next; + rlccb->rx_lost.next = new_lost; + + TRACELVL(5, (mcl_stdout, "<- RLC:AddLost (ok)\n")) + return MCL_OK; +} + + +/** + * + * @param mclcb session Control Block + */ +static INT32 +UpdateLossList (mcl_cb *mclcb) +{ + rlccb_t *rlccb; + lost_list_t *prev, *current; + TRACELVL(5, (mcl_stdout, "-> RLC: UpdateLossList\n")) + + ASSERT(mclcb); + rlccb = &(mclcb->rlccb); + prev = &(rlccb->rx_lost); + current = prev->next; + + while (current != NULL) { + if( --(current->pkt_remaining) == 0) { + /* this loss is too old : removing */ + prev->next = current->next; + free(current); + (rlccb->rx_nblost)--; + } else + prev = current; + current = prev->next; + } + + TRACELVL(5, (mcl_stdout, "<- RLC: UpdateLossList (ok)\n")) + return MCL_OK; +} + + +/** + * Frees all the lists and re-initializes the corresponding variables. + * @param mclcb session Control Block + */ +static void +FreeLists (mcl_cb *mclcb) +{ + INT32 i; + late_list_t *current_late; + lost_list_t *current_lost; + rlccb_t *rlccb; + + TRACELVL(5, (mcl_stdout, "-> RLC: FreeLists\n")) + ASSERT(mclcb); + rlccb = &(mclcb->rlccb); + + for (i = 0; irx_missing[i].next; + while (current_late != NULL) { + rlccb->rx_missing[i].next = current_late->next; + free(current_late); + current_late = rlccb->rx_missing[i].next; + } + rlccb->rx_missing[i].next = NULL; /* redundant, isn't it? */ + } + + current_lost = rlccb->rx_lost.next; + while ( current_lost != NULL ) { + rlccb->rx_lost.next = current_lost->next; + free(current_lost); + current_lost = rlccb->rx_lost.next; + } + rlccb->rx_lost.next = NULL; /* redundant, isn't it? */ + rlccb->rx_nblost = 0; + rlccb->rx_nblate = 0; + rlccb->rx_nblost_since_sp = 0; + rlccb->rx_nblate_since_sp = 0; +} + + +#endif /* RLC */ diff --git a/src/alc/mcl_rlc.h b/src/alc/mcl_rlc.h new file mode 100644 index 0000000..e638966 --- /dev/null +++ b/src/alc/mcl_rlc.h @@ -0,0 +1,275 @@ +/* $Id: mcl_rlc.h,v 1.7 2005/01/11 13:12:32 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main authors: Julien Laboure - julien.laboure@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * This file contains the headers for RLC congestion control module. + */ +#ifndef MCL_RLC_H /* { */ +#define MCL_RLC_H + +#ifdef RLC + +/** + * The 32 bit, ALC compliant, RLC congestion control header block. + */ +typedef struct { +#ifdef _BIT_FIELDS_LTOH + UINT8 rlc_reserved:7, /* Unused, must be 0x55 (1010101) */ + rlc_sp:1; /* Is this pkt a Synchronisation Point (SP)? */ +#else + UINT8 rlc_sp:1, /* Is this pkt a Synchronisation Point (SP)? */ + rlc_reserved:7; /* Unused, must be 0x55 (1010101) */ +#endif + UINT8 rlc_layer; /* packet's layer (indice) */ + UINT16 rlc_seqid; /* packet's Sequence number (per layer sequence) */ +} rlc_hdr_t; + + +typedef struct late_list { + struct late_list *next; /* next late */ + UINT16 seq_num;/* RLC Sequence Number */ + int ttw; /* Time To Wait before considering lost */ +} late_list_t; + + +typedef struct lost_list { + struct lost_list *next; /* next missing */ + int pkt_remaining; /* Number of packets to receive before we forget + this one */ +} lost_list_t; + + +/** + * RLC control block. + * Contains all information required for a sending or receiving RLC session. + */ +typedef struct rlccb { + /** Interval between 2 SPs at layer 0 (in µsec). */ + INT32 rlc_sp_cycle; + + /** Default Time To Wait for a late packet before assuming it's lost.*/ + INT32 rlc_pkt_timeout; + + /** Time for Deaf period after dropping a layer (in µsec). */ + INT32 rlc_deaf_period; + + /** + * If the amount of late packets between 2 SPs at top layer is + * <= rlc_late_accepted then a layer can be nonetheless added. + */ + INT32 rlc_late_accepted; + + /** + * If the amount of lost packets between 2 SPs at top layer is + * <= rlc_loss_accepted then a layer can be nonetheless added. + */ + INT32 rlc_loss_accepted; + + /** + * (rlc_loss_limit/rlc_loss_timeout) is the max loss rate for packet. + * If this rate is reached then we should drop the highest layer. + */ + INT32 rlc_loss_limit; + + /** + * (rlc_loss_limit/rlc_loss_timeout) is the max loss rate for packet. + * If this rate is reached then we should drop the highest layer. + */ + INT32 rlc_loss_timeout; + + /** Aggressive congestion ctrl setup for LAN tx. */ + INT32 rlc_lan_cc; + + /** + * For each layer, this table contains the value of the current + * sequence number. + */ + UINT16 tx_layers_seq[MAX_NB_TX_LAYERS]; + + /** For each layer, this table contains the date for the next SP. */ + UINT32 tx_next_sp[MAX_NB_TX_LAYERS]; + + /** + * For each layer, this table contains true if we are waiting + * for the first packet + */ + bool rx_first_pkt[MAX_NB_TX_LAYERS]; + + /** + * For each layer, this table contains true if we are waiting + * for the first SP after deaf. + */ + bool rx_first_sp[MAX_NB_TX_LAYERS]; + + /** + * For each layer, this table contains the expected sequence number + * of the next packet to receive. + */ + UINT16 rx_wait_for[MAX_NB_TX_LAYERS]; + + /** + * For each layer, this table contains a list of missing seq numbers. + */ + late_list_t rx_missing[MAX_NB_TX_LAYERS]; + + /** Number of late packets since the last SP. */ + UINT16 rx_nblate_since_sp; + + /** Number of recent late packets. */ + UINT16 rx_nblate; + + /** Number of lost packets since the last SP. */ + UINT16 rx_nblost_since_sp; + + /** Number of of recent lost packets */ + UINT16 rx_nblost; + + /** Current list of lost packets. */ + lost_list_t rx_lost; + + /** + * When in deaf period, it specifies the number of calls to + * rlc_rx_timer remaining before the end of the deaf period. + */ + mcl_itime_t rx_deaf_wait; + + /** Remaining time_count till next call to rlc_rx_timer function. */ + mcl_itime_t rlc_rx_timer_count; +} rlccb_t; + + +/* For infos about all these constants, */ +/* refer to the descriptions of the */ +/* corresponding rlccb member variables */ +/* + * Internet version + */ +#define RLC_SP_CYCLE 250000 /* 0.25s, for fast layer addition */ +#define RLC_DEAF_PERIOD 10000000 /* 10s, due to IGMP leave latency */ +#define RLC_LATE_ACCEPTED 0 +#define RLC_LOSS_ACCEPTED 0 +#define RLC_PKT_TIMEOUT 500000 +#define RLC_LOSS_LIMIT 1 +#define RLC_LOSS_TIMEOUT 20 +#define RLC_MAX_LATES 100 + +/* + * Aggressive version + * + * This profile is more robust to packet losses and can be used + * in situations where packet losses may be caused by something + * else than congestion, or with multicast routing protocols that + * can lead to an instable initial situation (e.g. with PIM-SM + * while moving from the shared tree to the source specific tree). + * Use with care... + * + * This mode can be set by changing the "rlc_aggr_cc" field in + * file mcl_tx_prof.cpp. + */ +#define RLC_LAN_DEAF_PERIOD 1000000 /* small (1s) as a LAN reacts quickly */ +#define RLC_LAN_LATE_ACCEPTED 1 +#define RLC_LAN_LOSS_ACCEPTED 1 +//#define RLC_LAN_LOSS_LIMIT 10 /* higher loss limit */ +#define RLC_LAN_LOSS_LIMIT 2 /* higher loss limit */ + + +/** + * Period in microseconds between two calls to the RLC timer function at + * a receiver. + * No call is made to the RLC timer function at a sender! + */ +extern UINT32 mcl_rlc_rx_period; + + +/* + * RLC function prototypes. + */ + +/** + * Initializes the RLC congestion control mechanism for a given session. + * This must be the called before any other calls to RLC functions + * @param mclcb session Control Block + */ +extern void rlc_init_session (class mcl_cb *mclcb); + + +/** + * Reset all SP variables at the sending side. + * Done just after transmitting the first packet to have synchronized SPs + * @param mclcb session Control Block + */ +extern void rlc_reset_tx_sp (class mcl_cb *mclcb); + + +/** + * Must be called when ending a session. + * @param mclcb session Control Block + */ +extern void rlc_end_session (class mcl_cb *mclcb ); + + +/** + * Fill the RLC header for each packet to send. + * @param mclcb session Control Block + * @param hdr_buff points to a buffer receiving the RLC header + * @param layer the layer for this packet + * @return Completion status (MCL_OK or an error code) + */ +extern int rlc_tx_fill_header (class mcl_cb *mclcb, + rlc_hdr_t *hdr_buff, UINT8 pkt_layer); + + +/** + * Analyse the packet's RLC header. + * @param mclcb session Control Block + * @param hdr_buff pointer to the RLC header. + * @return the layer number (>=0) if success, else the error + * code as defined in mcl_error.h. + */ +extern int rlc_rx_analyze_packet (class mcl_cb *mclcb, + rlc_hdr_t *hdr_buff); + + +/** + * Timer function, called periodically by the receiver. + * UINT32 mcl_rlc_rx_period = MCL_RLC_RX_PERIOD; + * is the period in microseconds between two calls to this function. + * @param mclcb session Control Block + * @return Completion status (MCL_OK or MCL_ERROR) + */ +extern mcl_error_status rlc_rx_timer (class mcl_cb *mclcb); + + +/** + * Used to set various RLC options and parameters. + * @param mclcb session Control Block + * @param optname a defined option name -> RLC_OPT_* + * @param optvalue pointer to the value for this option. + * @param optlen size of the argument pointed by optvalue. + * @return Completion status (MCL_OK or MCL_ERROR) + */ +extern mcl_error_status rlc_ctl (class mcl_cb *mclcb, INT32 optname, + void *optvalue, INT32 optlen); + +#endif /* } MCL_RLC_H */ + +#endif /* RLC */ diff --git a/src/alc/mcl_rx.cpp b/src/alc/mcl_rx.cpp new file mode 100644 index 0000000..367ae60 --- /dev/null +++ b/src/alc/mcl_rx.cpp @@ -0,0 +1,1099 @@ +/* $Id: mcl_rx.cpp,v 1.52 2005/05/23 15:37:18 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "mcl_includes.h" + +/******************************************************************************/ + +/** + * Default constructor. + */ +mcl_rx::mcl_rx () +{ +#ifdef SSM + this->ssm = false; +#endif + this->src_addr.reset(); + this->check_src_addr = false; + this->never_leave_base_layer = true; +} + +/** + * Default destructor. + */ +mcl_rx::~mcl_rx () +{ +#ifdef SSM + this->ssm = false; +#endif + this->src_addr.reset(); + this->check_src_addr = false; + this->never_leave_base_layer = true; +} + + +/******************************************************************************/ + + +/* + * private functions + */ + +/* uncomment the following define if you face physical layer duplications */ +// #define REMOVE_PHY_LAYER_DUPLICATES +#ifdef REMOVE_PHY_LAYER_DUPLICATES +static bool mcl_is_pkt_duplicated_at_phy_layer (mcl_cb *mclcb, + hdr_infos_t *hdr_infos, int layer); +#endif +#ifdef RSE_FEC +static void mcl_decode_all_adu (mcl_cb *mclcb); +static void mcl_decode_this_adu (mcl_cb *mclcb, adu_t *adu); +#endif /* RSE_FEC */ + + +/* + * Reception thread polling data regularly on the various mcast groups + */ +void* +mcl_rx_thread (void *arg) +{ + mcl_cb *mclcb; + + /* + * we don't sleep here but in the mcl_recv_pkt func. + * the unlock will be done there... + */ + mclcb = (mcl_cb*)arg; + ASSERT(mclcb != NULL); + TRACELVL(5, (mcl_stdout, "-> mcl_rx_thread:\n")) + +#ifdef WIN32 + mcl_thread_testcancel(mclcb); +#else // UNIX + /* + * cancellation is deferred till next check point , i.e. points + * in code where we know everything is in a stable state + */ + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE,NULL); + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED,NULL); + mcl_thread_testcancel(mclcb); +#endif + mclcb->lock(); + while (1) { + if (mclcb->fsm.is_closed(mclcb)) { + /* everything is finished */ + break; + } + if (mclcb->get_verbosity() >= 3) { + PRINT_OUT((mcl_stdout, + "Rx Thread %ld, ses_id=%d, time %d, state %s\n", + (UINT32)mclcb->rx_thread, mclcb->get_id(), + mcl_time_count, + mclcb->fsm.print_rx_state(mclcb))) + } + /*if (mclcb->fsm.close_already_rx(mclcb))*/ + if (mclcb->fsm.no_new_undup_du(mclcb)) { + /* + * we received all DUs, we now wait the application + * finishes to read all data and issues a mcl_close. + */ + mclcb->unlock(); + mcl_thread_testcancel(mclcb); + mcl_usleep(DFLT_POLLING_PERIOD); + mcl_thread_testcancel(mclcb); + mclcb->lock(); + } else { + /* get new pkts; mcl_process_pkt is called each time */ + mcl_recv_pkt(mclcb); + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_rx_thread:\n")) + mclcb->unlock(); + arg = 0; +#ifdef WIN32 + ExitThread(0); +#else + pthread_exit(arg); +#endif + return arg; /* unused */ +} + + +/* + * Get the packet received... + * This can be a pure signaling packet or a pure data packet, or + * a data packet plus a signaling header (usual case). + */ +void +mcl_process_pkt (mcl_cb* mclcb, + mcl_rx_pkt *pkt, /* recv'd pkt */ + mcl_addr *saddr, /* src addr */ + int layer) +{ + hdr_infos_t hdr_infos; /* info extracted from the LCT header */ + du_t *du; /* DU descriptor of the data buf */ + block_t *blk; /* block to which the DU belongs */ + //int layer; + int len; /* data len */ + adu_t *adu; /* ADU to which the DU belongs */ + int hlen = 0; /* total header length */ + int ret = 0; + + TRACELVL(5, (mcl_stdout, "-> mcl_process_pkt:\n")) + ASSERT(pkt && pkt->pkt_len > 0); + ASSERT(saddr && saddr->get_port() > 0); + TRACELVL(4, (mcl_stdout, + "mcl_process_pkt: ses_id=%d, from %s/%d, len=%d, pkt_struct=x%x\n", + mclcb->get_id(), saddr->get_addr_string(), saddr->get_port(), + pkt->pkt_len, (int)pkt)) + if (mclcb->fsm.is_closed(mclcb)) { + /* + * the session has been closed in the meanwhile... ignore + */ + TRACELVL(5, (mcl_stdout, + "<- mcl_process_pkt: ignored (session closed)\n")) + delete pkt; + return; + } + if (mclcb->get_verbosity() >= 4) { + /* dump at most 16 32-bit words */ + mcl_dump_buffer(pkt->get_buf(), pkt->pkt_len, 16); + } + /* + * process the LCT header (extension then fixed header) first + */ + memset(&hdr_infos, 0, sizeof(hdr_infos)); + hdr_infos.FPI_present = hdr_infos.FTI_present = hdr_infos.NONEWADU_present = hdr_infos.close = false; + if (pkt->pkt_len < (int)(sizeof(fixed_lct_hdr_t))) { + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR too short %d\n", pkt->pkt_len)) + goto bad_hdr; + } + if ((hlen = alc_hdr_parse(mclcb, (fixed_lct_hdr_t*)pkt->get_buf(), + &hdr_infos, pkt->pkt_len)) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR, bad LCT header\n")) + goto bad_hdr; + } + /* + * right session ? check the {source_addr; TSI} + */ + if ((int)hdr_infos.demux_label != mclcb->demux_label || + (mclcb->rx.check_src_addr && mclcb->rx.src_addr.addr_is_equal(*saddr) == false)) { + TRACELVL(4, (mcl_stdout, + " mcl_process_pkt: pkt for bad session (expected %s/%d, got %s/%d)\n", + mclcb->rx.src_addr.get_addr_string(), mclcb->demux_label, + saddr->get_addr_string(), hdr_infos.demux_label)) + mclcb->stats.bad_demux_label++; + goto bad; + } + /* + * Some network configurations have the bad idea to duplicate + * packets at the physical layer (this is sometimes the case + * with some switchs). So remove immediately this kind of + * duplicates, without taking them into account in statistics, + * and before doing congestion control checks. + */ +#ifdef REMOVE_PHY_LAYER_DUPLICATES + if (mcl_is_pkt_duplicated_at_phy_layer(mclcb, &hdr_infos, layer)) { + TRACELVL(5, (mcl_stdout, + "<- mcl_process_pkt: ignored (duplicated pkt at physical layer)\n")) + delete pkt; + return; + } +#endif /* REMOVE_PHY_LAYER_DUPLICATES */ + /* + * process the congestion control header then + */ + if (mclcb->congestion_control == NO_CC) { + /* + * In no congestion control mode there is no CC header. + * Required for FLUTE interoperability tests, but it + * prevents loss statistics! + */ + layer = 0; + } else { + /* process the congestion header */ +#ifdef RLC + if (mclcb->congestion_control == RLC_CC) { + layer = rlc_rx_analyze_packet(mclcb, + (rlc_hdr_t*)(pkt->get_buf() + 4)); + } else +#endif +#ifdef FLIDS + if (mclcb->congestion_control == FLID_SL_CC) { + layer = FLIDs_rx_AnalyzePacket(mclcb, + (flids_hdr_t*)(pkt->get_buf() + 4)); + } +#endif + if (layer < 0) { + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR while processing RLC/FLIDS header (error=%d)\n", layer)) + goto bad_hdr; + } + } + /* + * process the multiple signaling headers if any + */ + if (hdr_infos.FTI_present) { + /* FEC Object Transmission Information (FTI) HE present */ + ret = mcl_process_sig (mclcb, EXT_FTI, &hdr_infos, saddr); + } + if (hdr_infos.FDT_present) { + /* FLUTE's File Delivery Table (FDT) HE present */ + ret = mcl_process_sig (mclcb, EXT_FDT, &hdr_infos, saddr); + } +#ifdef METAOBJECT_USED + if (hdr_infos.MODT_present) { + /* Object Delivery Table (MODT) HE present */ + ret = mcl_process_sig (mclcb, EXT_MODT, &hdr_infos, saddr); + } +#endif + if ((ret >= 0) && hdr_infos.NONEWADU_present) { + /* LCT equivalent to NONEWADU */ + if (!mclcb->fsm.no_new_adu(mclcb)) { + ret = mcl_process_sig (mclcb, EXT_NONEWADU, + &hdr_infos, saddr); + } + /* else ignore (this is a duplicated announce) */ + } + /* + * Warngin: SIG_CLOSE has to be processed at the end of packet + * reception + */ + if (ret < 0) { + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR in header processing\n")) + goto bad_hdr; + } + if (mclcb->rx_flute.delete_current_packet == true) { + /* in FLUTE_DELIVERY mode, do not store adu & packet */ + mclcb->rx_flute.delete_current_packet = false; + TRACELVL(5, (mcl_stdout, + "<- mcl_process_pkt: ignored (FLUTE_DELIVERY)\n")) + delete pkt; + return; + } + mclcb->stats.rx_totbytes += hlen; /* data len incr later; see below...*/ + /* + * check what we got... + */ + len = pkt->pkt_len - hlen; /* data len */ + ASSERT(len >= 0); + if (len == 0) { + /* not a data packet... nothing else to do */ + /* we need to check SIG_CLOSE now */ + if (hdr_infos.close) { + /* LCT equivalent to CLOSE */ + ret = mcl_process_sig (mclcb, SIG_CLOSE, &hdr_infos, + saddr); + if (ret < 0) { + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR in SIG_CLOSE processing\n")) + goto bad_hdr; + } + } + delete pkt; /* no more necessary */ + TRACELVL(5, (mcl_stdout, "<- mcl_process_pkt: only SIG\n")) + return; + } + if (hdr_infos.FPI_present == false) { + /* error, data packet without any payload info */ + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR, data packet without any payload info\n")) + goto bad_hdr; + } + if (mclcb->get_verbosity() >= 1) + mcl_print_recvd_du(mclcb, 0, layer, &hdr_infos); + /* + * create its descriptor + */ + du = CreateDU(mclcb); + du->seq = hdr_infos.idf_du; + du->len = len; + du->data = pkt->get_buf() + hlen; + du->pkt = pkt; +#ifdef FEC + du->is_fec = hdr_infos.is_fec; +#endif + /* + * update stats now (includes duplicated packets) + */ + mclcb->stats.rx_pkts_per_lvl[layer]++; + mclcb->stats.rx_bytes_per_lvl[layer] += len; +#ifdef FEC + if (du->is_fec) { + mclcb->stats.rx_fec_pkts++; + mclcb->stats.rx_fec_bytes += len; + } else { +#endif + mclcb->stats.rx_pkts++; + mclcb->stats.rx_bytes += len; +#ifdef FEC + } +#endif + mclcb->stats.rx_totbytes += len;/* sig hlen already incr; see above...*/ + /* + * find the right ADU first... + */ + if (!(adu = mclcb->rx_window.find_adu(mclcb, hdr_infos.idf_adu, + hdr_infos.FDT_instanceid))) { + /* + * orphan du (i.e. we receive a DU before the announcement + * of the corresponding ADU). + * XXX: put it in mclcb->rx_window.du_head list... TO DO. + */ + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR1, orphan DU [%d/%d/%d] (no adu)\n", + hdr_infos.idf_adu, hdr_infos.idf_block, du->seq)) + free(du); + goto bad; + } + if (adu->rx_status >= ADU_STATUS_DECODED) { + /* useless du as the ADU is already decoded and/or delivered */ + TRACELVL(3, (mcl_stdout, "mcl_process_pkt: duplicated0\n")) + goto duplicated; + } + /* + * ... and then the right block... + */ + if (!(blk = FindBlock(mclcb, hdr_infos.idf_block, adu->block_head, + adu))) { + /* + * orphan du (we received a DU before the announcement + * of its ADU). Should put it in mclcb->rxlvl.du_head... TO DO. + */ + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR2, orphan DU [%d/%d/%d] (no block)\n", + hdr_infos.idf_adu, hdr_infos.idf_block, du->seq)) + free(du); + goto bad; + } + if (blk->rx_status == BLK_STATUS_DECODED) { + /* useless du as the block is already decoded */ + TRACELVL(3, (mcl_stdout, "mcl_process_pkt: duplicated1\n")) + goto duplicated; + } + if (blk->rx_status == BLK_STATUS_COMPLETED) { +#ifdef FEC + if (du->is_fec) { + /* can't do anything interesting with it */ + /* useless du as block already completed */ + TRACELVL(3, (mcl_stdout, + "mcl_process_pkt: duplicated2 fec\n")) + goto duplicated; + } else { +#endif + /* it is possible that this data DU can replace a + * FEC du. Depends if DU has already been received + * or not! + * If possible, do it as FEC decoding is simplified. + */ +#ifdef FEC + } +#endif + } + du->block = blk; + ASSERT(du->block->adu == adu); + /* + * insert it in the DU list if appropriate... + */ +#ifdef FEC + if (du->is_fec) { +#ifdef LDPC_FEC + if ((adu->fec_scheme != MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0) && + (adu->fec_scheme != MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1)) +#endif + { + /* register the FEC DU for later decoding */ + if (InsertDU(mclcb, du, &(blk->fec_du_head)) <= 0) { + /* duplicated FEC du */ + TRACELVL(3, (mcl_stdout, + "mcl_process_pkt: duplicated3 fec\n")) + goto duplicated; + } + blk->fec_du_nb_in_list++; + } +#ifdef LDPC_FEC + else { + /* + * Do not register FEC DUs in case of LDGM codes since + * they will be immediately free'ed after the + * fec.decode() call. + * A drawback is that there's no way to detect + * duplicated FEC DUs, but it makes the total amount + * of memory needed far smaller, which is of prime + * interest! + * This is not a problem though for decoding, since the + * LDPC/LDGM codec automatically detects it. + */ + } +#endif + } else +#endif /* FEC */ + { + /* + * source DU + */ + if (InsertDU(mclcb, du, &(blk->du_head)) <= 0) { + /* duplicated du */ + TRACELVL(3, (mcl_stdout, + "mcl_process_pkt: duplicated3 data\n")) + goto duplicated; + } + blk->du_nb_in_list++; + adu->recvd_src_data += du->len; + } + /* + * store data buffer either in vrfile (when desired and needed) + * or in physical memory, whichever is the most appropriate. + */ + if (mclcb->rx_storage.store_data(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR: Virtual Rx Memory service failed\n")) + goto bad; + } +#ifdef RSE_FEC + /* + * there is one case where having a duplicated data DU is not + * an issue. Check it... + */ + if ((du->is_fec == false) && + (adu->fec_scheme == MCL_FEC_SCHEME_RSE_129_0) && + blk->rx_status == BLK_STATUS_COMPLETED) { + /* + * this data DU can indeed replace a FEC DU in case of RSE + */ + /* TODO: free one FEC du immediately! */ + /* we need to check SIG_CLOSE now */ + if (hdr_infos.close) { + /* LCT equivalent to CLOSE */ + ret = mcl_process_sig(mclcb, SIG_CLOSE, + &hdr_infos, saddr); + if (ret < 0) { + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR in SIG_CLOSE processing\n")) + goto bad_hdr; + } + } + mclcb->stats.rx_dupl_pkts ++; + mclcb->stats.rx_dupl_bytes += du->len; + TRACELVL(3, (mcl_stdout, "mcl_process_pkt: duplicated4 data\n")) + TRACELVL(5, (mcl_stdout, "<- mcl_process_pkt:\n")) + return; + } +#endif /* RSE_FEC */ + /* + * update stats now (non-duplicated packets only) + */ + mclcb->stats.rx_undup_pkts_per_lvl[layer]++; + /* + * perform FEC decoding now. + * The codec used is specified by the + * {fec_encoding_id; fec_instance_id} fields. + */ + switch (adu->fec_scheme) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + /* + * was du the last DU of a block/ADU ? + */ + if (mcl_rx_enough_du(mclcb, blk)) { + if (mclcb->postpone_fec_decoding) { + /* ok, we rx enough data or FEC DUs, + * just mark it */ + blk->rx_status = BLK_STATUS_COMPLETED; + } else { + /* ok, we rx enough data or FEC DUs, + * so decode */ + mclcb->fec.decode(mclcb, blk); + } + } + break; +#endif /* RSE_FEC */ + +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + /* + * iterative decoding takes place for all incoming packets... + * Start by specifying the FEC codec used with this ADU. + */ + mclcb->fec.set_fec_code(mclcb, adu->fec_scheme); + mclcb->fec.decode(mclcb, du); + if (du->is_fec) { + /* this FEC DU is no longer needed once + * fec.decode() has been called + * (they have not been stored in fec du list) */ + mclcb->rx_storage.free_data(mclcb, du); + free(du); + } + break; +#endif + + case MCL_FEC_SCHEME_NULL: + /* + * was du the last DU of a block/ADU ? + */ + if (mcl_rx_enough_du(mclcb, blk)) { + blk->rx_status = BLK_STATUS_DECODED; + } + break; + + default: + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR: unsupported FEC scheme %d\n", + adu->fec_scheme)) + mcl_exit(-1); + } + /* + * see if an ADU has been completely received, and in that + * case if some data can be delivered to the application. + */ + if (mcl_rx_new_completed_adu(mclcb, adu)) { + if (mclcb->get_verbosity() >= 1) + PRINT_OUT((mcl_stdout, "End of ADU %d\n", adu->seq)) + if (mclcb->get_stats_level() == 2) + mcl_print_rx_stats(mclcb); +#ifdef RSE_FEC + if (!mclcb->postpone_fec_decoding && + adu->rx_status == ADU_STATUS_COMPLETED) { + /* do not wait, decode every block of this adu */ + mcl_decode_this_adu (mclcb, adu); + } +#endif /* RSE_FEC */ + mclcb->rx_window.mark_ready_adu(); /* remember it */ + if (mclcb->fsm.no_new_adu(mclcb) && + mclcb->rx_window.check_if_all_adu_completed(mclcb) == true) { + /* + * we know we won't receive any new ADU and + * it was the last packet we were waiting for... + */ + if (mclcb->get_verbosity() >= 1) + PRINT_OUT((mcl_stdout, "All ADUs received\n")) + mclcb->fsm.update_rx_state(mclcb, REVENT_ALL_DU_RECV); + if (mclcb->get_stats_level() >= 1) { + mcl_print_rx_stats(mclcb); + mcl_print_final_stats(mclcb); + } + /* + * unsubscribe to all layers (incl. layer 0) to avoid + * receiving useless packets + */ + mcl_drop_layer(mclcb, MCL_ALL_LAYERS, MCL_DO_IT); +#ifdef RSE_FEC + /* + * we can now decode all ADUs if in postpone mode + */ + if (mclcb->postpone_fec_decoding) { + mcl_decode_all_adu(mclcb); + } +#endif /* RSE_FEC */ + } + } + /* we need to check SIG_CLOSE now */ + if (hdr_infos.close) { + /* LCT equivalent to CLOSE */ + ret = mcl_process_sig (mclcb, SIG_CLOSE, &hdr_infos, saddr); + if (ret < 0) { + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR in header processing\n")) + goto bad_hdr; + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_process_pkt:\n")) + return; + +duplicated: + /* we need to check SIG_CLOSE now */ + if (hdr_infos.close) { + /* LCT equivalent to CLOSE */ + ret = mcl_process_sig (mclcb, SIG_CLOSE, &hdr_infos, saddr); + if (ret < 0) { + PRINT_ERR((mcl_stderr, + "mcl_process_pkt: ERROR in header processing\n")) + goto bad_hdr; + } + } + mclcb->stats.rx_dupl_pkts ++; + mclcb->stats.rx_dupl_bytes += du->len; /* do it before the free(du)! */ + delete pkt; + free(du); + TRACELVL(5, (mcl_stdout, "<- mcl_process_pkt: duplicated\n")) + return; + +bad_hdr: + mclcb->stats.bad_hdr++; +bad: + mclcb->stats.errors++; + delete pkt; + TRACELVL(5, (mcl_stdout, "<- mcl_process_pkt: ERROR\n")) + return; +} + + +/** + * Identify packets duplicated at the physical layer. + * Some network configurations have the bad idea to duplicate + * packets at the physical layer (this is sometimes the case + * with some switchs). So identify immediately this kind of + * duplicates. + * This function has limitations: + * - it only works with data packets + * - since we compare the new packet with the previous one, it + * only works if a duplicate is sent immediately (not necessarily + * true with high transmission rates) + * - it only works with a single source (with two or more sources, + * we should keep a copy of idf values per source) + * + * @param mclcb + * @param hdr_infos + * @param lay layer where packet has been received + * @return true if packet is duplicated, false otherwise. + */ +#ifdef REMOVE_PHY_LAYER_DUPLICATES +static bool +mcl_is_pkt_duplicated_at_phy_layer (mcl_cb *mclcb, + hdr_infos_t *hdr_infos, + int layer) +{ + static UINT32 prev_idf_adu[MAX_NB_TX_LAYERS]; + static UINT32 prev_idf_block[MAX_NB_TX_LAYERS]; + static UINT32 prev_idf_du[MAX_NB_TX_LAYERS]; + static UINT32 demux_label; + static bool initialized = false; + bool dup; + int i; + + if (!initialized) { + /* initialize everything with a random value */ + for (i = 0; i < MAX_NB_TX_LAYERS; i++) { + prev_idf_adu[i] = prev_idf_block[i] = + prev_idf_du[i] = 32109876; + } + demux_label = 32109876; + initialized = true; + } + dup = false; + if (hdr_infos->FPI_present) { + if ((hdr_infos->idf_du == prev_idf_du[layer]) && + (hdr_infos->idf_block == prev_idf_block[layer]) && + (hdr_infos->idf_adu == prev_idf_adu[layer]) && + (hdr_infos->demux_label == demux_label)) { + dup = true; + } else { + prev_idf_du[layer] = hdr_infos->idf_du; + prev_idf_block[layer] = hdr_infos->idf_block; + prev_idf_adu[layer] = hdr_infos->idf_adu; + demux_label = hdr_infos->demux_label; + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_is_pkt_duplicated_at_phy_layer: %s\n", + (dup ? "yes" : "no"))) + return dup; +} +#endif /* REMOVE_PHY_LAYER_DUPLICATES */ + + +/* + * Process the various types of signalling + * returns: < 0, if error + * >= 0 if ok + */ +int +mcl_process_sig (mcl_cb *mclcb, + int type, /* sig type */ + hdr_infos_t *hdr_infos, + mcl_addr *saddr) /* src addr or NULL */ +{ + adu_t *adu; + + ASSERT(!mclcb->fsm.is_closed(mclcb)); + switch (type) { + case EXT_FDT: /* File Delivery Table (FLUTE specific) */ + TRACELVL(5, (mcl_stdout, "-> mcl_process_sig: EXT_FDT (%d)\n", + type)) + break; +#ifdef METAOBJECT_USED + case EXT_MODT: /* Meta-Object Delivery Table */ + TRACELVL(5, (mcl_stdout, "-> mcl_process_sig: EXT_MODT (%d)\n", + type)) + if (mclcb->meta_obj_layer->in_use() == false) mclcb->meta_obj_layer->set_in_use(true); + break; +#endif + case EXT_FTI: { /* FEC Object Transmission Information */ + block_t *blk; + u_int rem; + UINT32 tot_blk_nb; /* total nb of blocks required*/ + UINT32 k_for_this_blk; /* all blks are not same len */ + UINT32 blk_seq; /* block seq number */ + mcl_blocking_struct_t *bs; /* ptr to ADU blocking struct */ +#ifdef FEC + double fec_ratio = 0.0;/* n/k value, constant for all blocks */ + /* even if some blks are shorter */ +#endif + + TRACELVL(5, (mcl_stdout, "-> mcl_process_sig: EXT_FTI (%d)\n", + type)) + adu = mclcb->rx_window.find_adu(mclcb, hdr_infos->idf_adu, + hdr_infos->FDT_instanceid); + if (adu && !(adu->ia_adu)) { + /* + * ADU already announced and completed! + * NB: to counter losses, new ADUs are + * announced in each data packet (EXT_FTI) + */ + break; + } + if (mclcb->get_verbosity() >= 1) { + PRINT_OUT((mcl_stdout, + "New ADU: seq=%d, len=%d, max_k=%d, max_n=%d, symbol_size=%d\n", + hdr_infos->idf_adu, hdr_infos->adu_len, + hdr_infos->max_k, hdr_infos->max_n, + hdr_infos->symbol_len)) + } + if (adu == NULL) { + /* + * completely new ADU, so update state and + * allocate the struct... + * if sequence number == 0 and if in FLUTE mode or + * object aggregation mode, do not update fsm (see NB_1 note + * in mcl_fsm.cpp in the receivers state machine). + */ + if (!(hdr_infos->idf_adu == 0 && mclcb->fsm.get_rx_state(mclcb) == RSTATE_FINISH_RX)) + { + mclcb->fsm.update_rx_state(mclcb, REVENT_NEW_ADU); + } + /* + * Without FLUTE, always store the ADU. + * With FLUTE, only store the ADU if it is a FDT, or + * it has been requested, or all ADUs have been + * requested. + */ + if ((mclcb->is_flute_compatible() == false) || + (hdr_infos->idf_adu == 0) || + (mclcb->rx_flute.use_flute_store_all_adus_by_default() == true) || + (mclcb->rx_flute.is_toi_requested(mclcb, hdr_infos->idf_adu) == true)) { + adu = mcl_create_adu(mclcb); + adu->seq = hdr_infos->idf_adu; + adu->FDT_instanceid = hdr_infos->FDT_instanceid; + if (mclcb->rx_window.insert_adu(mclcb, adu) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_process_sig: ERROR, insert_adu() failed\n")) + return -1; + } + mclcb->stats.adus_announced++; + } else { + /* do not store the adu */ + mclcb->rx_flute.delete_current_packet = true; + return 0; + } + } else { + /* no longer implicite */ + adu->ia_adu = 0; + } + adu->len = hdr_infos->adu_len; + adu->max_k = hdr_infos->max_k; + /* FEC codec used for this ADU */ + adu->fec_encoding_id = hdr_infos->fec_encoding_id; + adu->fec_instance_id = hdr_infos->fec_instance_id; + if (mclcb->fec.enc_inst_to_scheme (mclcb, + adu->fec_encoding_id, + adu->fec_instance_id, + &(adu->fec_scheme)) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_process_sig: EXT_FTI: ERROR, unknown FEC scheme (%d/%d)\n", + hdr_infos->fec_encoding_id, + hdr_infos->fec_instance_id)) + return -1; + } + /* store src addr for mcl_recvfrom() */ + adu->addr = *saddr; + adu->symbol_len = hdr_infos->symbol_len; + /* + * compute the blocking struct + */ + bs = &(adu->blocking_struct); + mcl_compute_blocking_struct(adu->max_k, adu->len, + adu->symbol_len, bs); + /* + * and remember max_n (not always transmitted in FTI) + * NB: the FEC ratio is the same for all blocks of this adu + */ + switch (adu->fec_scheme) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + adu->max_n = hdr_infos->max_n; + fec_ratio = (double)adu->max_n / (double)adu->max_k; + mclcb->fec.set_fec_code(mclcb, + MCL_FEC_SCHEME_RSE_129_0); + break; +#endif /* RSE_FEC */ + +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + adu->max_n = hdr_infos->max_n; + fec_ratio = (double)adu->max_n / (double)adu->max_k; + mclcb->fec.set_fec_code(mclcb, + MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0); + break; + + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + adu->max_n = hdr_infos->max_n; + fec_ratio = (double)adu->max_n / (double)adu->max_k; + mclcb->fec.set_fec_code(mclcb, + MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1); + break; +#endif /* LDPC_FEC */ + + case MCL_FEC_SCHEME_NULL: + adu->max_n = adu->max_k; + mclcb->fec.set_fec_code(mclcb, MCL_FEC_SCHEME_NULL); + break; + + default: + /* NB: FEC Enc. ID 128 no longer supported */ + mcl_exit(-1); + } + + /* + * remember them just in case. Do not get confused by the + * ADU max_k/n values and the FEC codec maximum k/n values. + */ + mclcb->fec.set_k(adu->max_k); + mclcb->fec.set_n(adu->max_n); + /* + * allocate the block structs... + * do it simply: allocate a tab of block_t structs + * rather than a linked list! + */ + tot_blk_nb = bs->block_nb; + if (!(blk = (block_t*)calloc(tot_blk_nb, sizeof(block_t)))) { + PRINT_ERR((mcl_stderr, + "mcl_process_sig: ERROR, no memory\n")) + mcl_exit(-1); + } + adu->block_head = blk; + /* ... and now initialize all the blocks */ + rem = adu->len; + for (blk_seq = 0; blk_seq < tot_blk_nb; blk_seq++) { + if (blk_seq < bs->I) + k_for_this_blk = bs->A_large; + else + k_for_this_blk = bs->A_small; + blk->adu = adu; + blk->seq = blk_seq; + blk->k = k_for_this_blk; + blk->len = min(rem, k_for_this_blk * adu->symbol_len); + switch (adu->fec_scheme) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + blk->n = (UINT32)floor((double)blk->k * fec_ratio); + break; +#endif /* RSE_FEC */ +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0: + case MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1: + /* + * WARNING: due to the way fec_key is passed + * to receiver, the same value is used for + * all blocks of an ADU + */ + blk->fec_key = hdr_infos->fec_key; + blk->n = (UINT32)floor((double)blk->k * fec_ratio); + TRACELVL(4, (mcl_stdout, + " New ADU: LDPC/LDGM blk_seq=%d: key=%d, (k;n)=(%d;%d) fec_ratio=%.3f\n", + blk->seq, blk->fec_key, blk->k, blk->n, + (float)fec_ratio)) + break; +#endif /* LDPC_FEC */ + default: + ASSERT(adu->fec_scheme == MCL_FEC_SCHEME_NULL); + blk->n = blk->k; /* no FEC here */ + break; + } + /* + * blk->du_head, fec_du_head, fec_du_nb_in_list, du_rx + * already set to NULL/0 + */ + rem -= blk->len; + blk++; /* switch to next block */ + } + + TRACELVL(4, (mcl_stdout, " New ADU: %d blocks, max_block_len=%d (%d DUs), min_block_len=%d (%d DUs)\n", + adu->blocking_struct.block_nb, adu->block_head->len, adu->block_head->k, + (blk-1)->len, (blk-1)->k)) + break; + } + + case EXT_NONEWADU: { + u_int seq; + + TRACELVL(5, (mcl_stdout, "-> mcl_process_sig: EXT_NONEWADU (%d)\n", type)) + /* this sig header must not be a duplicate */ + ASSERT(!mclcb->fsm.no_new_adu(mclcb)); + ASSERT(hdr_infos->max_idf_adu >= mcl_iss); + if (mclcb->get_verbosity() >= 1) + mcl_print_recvd_du(mclcb, EH_SIG, type, hdr_infos); + ASSERT(mclcb->is_flute_compatible() == false); + mclcb->fsm.update_rx_state(mclcb, REVENT_NO_NEW_ADU); + /* + * check if there are implicit declarations of NEWADU, + * i.e. ADUs that we know exist thanks to the max_adu_idf + * info of NONEWADU, but for which we did not receive any + * packet yet... + */ + /* search more efficient in ascending ADU seq number order */ + for (seq = mcl_iss; seq <= hdr_infos->max_idf_adu; seq++) { + adu = mclcb->rx_window.find_adu(mclcb, seq, 0); + if (!adu) { + adu = mcl_create_adu(mclcb); + mclcb->stats.adus_announced++; + adu->seq = seq; + adu->FDT_instanceid = 0; + adu->ia_adu = 1; /* implicitely announced */ + if (mclcb->rx_window.insert_adu(mclcb, adu) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_process_sig: ERROR, insert_adu() failed\n")) + return -1; + } + } + } + /* + * did we receive everything ? + */ + if (mclcb->rx_window.check_if_all_adu_completed(mclcb) == true) { + if (mclcb->get_verbosity() >= 1) + PRINT_OUT((mcl_stdout, "\nAll ADUs received\n")) + /* + * the receiver has finished + */ + mclcb->fsm.update_rx_state(mclcb, REVENT_ALL_DU_RECV); + if (mclcb->get_stats_level() >= 1) { + mcl_print_rx_stats(mclcb); + mcl_print_final_stats(mclcb); + } + /* + * unsubscribe to all layers (incl. layer 0) to avoid + * receiving useless packets + */ + mcl_drop_layer(mclcb, MCL_ALL_LAYERS, MCL_DO_IT); +#ifdef RSE_FEC + /* + * we can now decode all ADUs if in postpone mode + */ + if (mclcb->postpone_fec_decoding) { + mcl_decode_all_adu(mclcb); + } +#endif /* RSE_FEC */ + } /* otherwise wait... */ + break; + } + + case SIG_CLOSE: { + TRACELVL(5, (mcl_stdout, "-> mcl_process_sig: SIG_CLOSE (%d)\n", type)) + if (mclcb->fsm.close_already_rx(mclcb)) { + /* this is a duplicated announce; ignore */ + break; + } + if (mclcb->get_verbosity() >= 2) + mcl_print_recvd_du(mclcb, EH_SIG, type, hdr_infos); + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_RECV); + ASSERT(mclcb->fsm.no_new_adu(mclcb)); + if (mclcb->get_stats_level() >= 1) { + mcl_print_rx_stats(mclcb); + mcl_print_final_stats(mclcb); + } + break; + } + + default: + PRINT_ERR((mcl_stderr, + "mcl_process_sig: ERROR, unknown SIG type: %d\n", type)) + return -1; + } + /* update stats */ + //mclcb->stats.rx_sig_pkts++; /* there is a SIG header */ + TRACELVL(5, (mcl_stdout, "<- mcl_process_sig: ok\n")) + return 0; +} + + +#ifdef RSE_FEC /* { */ +/* + * we have just finished to receive everything. Now make sure that + * all blocks of all ADUs are actually decoded. + * Used in postpone_fec_decoding mode after having received everything. + * Specific to RSE ! + */ +static void +mcl_decode_all_adu (mcl_cb *mclcb) +{ + adu_t *adu; + adu_t *first; + + TRACELVL(5, (mcl_stdout, "-> mcl_decode_all_adu:\n")) + ASSERT(mclcb->postpone_fec_decoding); + first = adu = mclcb->rx_window.get_first_adu(mclcb); + do { + ASSERT(adu); + adu = adu->prev; + if (adu->fec_scheme == MCL_FEC_SCHEME_RSE_129_0) { + /* postponed decoding only applies to RSE */ + if (adu->rx_status == ADU_STATUS_COMPLETED) { + mcl_decode_this_adu(mclcb, adu); + } /* else nothing to do */ + } + /* nothing to do with other FEC codes */ + } while (adu != first); + TRACELVL(5, (mcl_stdout, "<- mcl_decode_all_adu: ok\n")) +} + + +/** + * RSE specific function. + */ +static void +mcl_decode_this_adu (mcl_cb *mclcb, + adu_t *adu) +{ + block_t *blk; + int i; + + ASSERT(adu->rx_status == ADU_STATUS_COMPLETED); + ASSERT(adu->fec_scheme == MCL_FEC_SCHEME_RSE_129_0); + for (i = adu->blocking_struct.block_nb, blk = adu->block_head; i > 0; i--, blk++) { + if (blk->rx_status == BLK_STATUS_DECODED) + continue; + if (mclcb->fec.decode(mclcb, blk) < 0) { + PRINT_ERR((mcl_stderr, "mcl_decode_this_adu: ERROR, decode() failed\n")) + mcl_exit(-1); + } + } +#ifdef GET_SYSINFO + mcl_print_sysinfo(mclcb); +#endif + adu->rx_status = ADU_STATUS_DECODED; +} +#endif /* } RSE_FEC */ + + diff --git a/src/alc/mcl_rx.h b/src/alc/mcl_rx.h new file mode 100644 index 0000000..f8fe897 --- /dev/null +++ b/src/alc/mcl_rx.h @@ -0,0 +1,81 @@ +/* $Id: mcl_rx.h,v 1.1 2005/05/23 14:35:54 roca Exp $ */ +/* + * Copyright (c) 2005 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_RX_H +#define MCL_RX_H + + +/** + * This Class controls many aspects related to transmissions. + */ +class mcl_rx { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + mcl_rx (); + + /** + * Default destructor. + */ + ~mcl_rx (); + + + /****** Public Attributes *********************************************/ + +#ifdef SSM + /** + * True if we are using SSM multicast in this session. + * In that case, src_addr is mandatory... + */ + bool ssm; +#endif + + /** + * Unicast address of the source. + * Used by the TSI/saddr check of incoming pkts. + * This address is also used in SSM mode during SSM multicast join. + * Port is not specified. + */ + class mcl_addr src_addr; + + /* true if TSI/saddr is done and src_addr set */ + bool check_src_addr; + + + /* required by MCL_WAIT_EVENT_CLOSED */ + bool never_leave_base_layer; + +private: + /****** Private Members ***********************************************/ + + /****** Private Attributes ********************************************/ +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +#endif // !MCL_RX_H + diff --git a/src/alc/mcl_rx_storage.cpp b/src/alc/mcl_rx_storage.cpp new file mode 100644 index 0000000..bc80364 --- /dev/null +++ b/src/alc/mcl_rx_storage.cpp @@ -0,0 +1,276 @@ +/* $Id: mcl_rx_storage.cpp,v 1.5 2005/05/17 12:36:58 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + +/** + * Default constructor. + * Allocates the data buffer with the size provided. + */ +mcl_rx_pkt::mcl_rx_pkt (INT32 max_size) +{ + this->buf = new char[max_size]; + ASSERT(this->buf); +#ifdef LDPC_FEC /* LDPC DecodeFecStep requires that buffer be + * cleared (problem of last packet of a block) + * not required by RSE; padding of last pkt of + * a block cleared while copying into temp buf + */ + memset(this->buf, 0, max_size); +#endif + this->buf_len = max_size; + this->pkt_len = 0; +} + + +/** + * Default destructor. + * This destructor deletes both the pkt and the buffer, but NOT the DU + * (if any). + */ +mcl_rx_pkt::~mcl_rx_pkt () +{ + if (this->buf) { + delete [] this->buf; + this->buf = NULL; + } + this->buf_len = 0; + this->pkt_len = 0; +} + + +/******************************************************************************/ + + +/** + * Constructor. + */ +mcl_rx_storage::mcl_rx_storage() +{ + this->vrmem_desired = true; + this->vrmem_used = false; +#ifdef VIRTUAL_RX_MEM + this->vrmem = NULL; +#endif +} + + +/** + * Destructor. + */ +mcl_rx_storage::~mcl_rx_storage() +{ +#ifdef VIRTUAL_RX_MEM + this->close_vrmem(NULL); +#endif + this->vrmem_desired = true; +} + + +#ifdef VIRTUAL_RX_MEM +/** + * Closes the Virtual receive memory service, when applicable. + */ +void +mcl_rx_storage::close_vrmem (class mcl_cb *const mclcb) +{ +#ifdef DEBUG + if (mclcb) { + TRACELVL(5, (mcl_stdout, " mcl_rx_storage::close_vrmem:\n")) + } +#endif + if (this->vrmem_used) { + delete this->vrmem; + this->vrmem = NULL; + this->vrmem_used = false; + } +} +#endif + + +/** + * Stores data of the DU either in RAM or in the vrmem file, + * whichever is the most appropriate. + */ +mcl_error_status +mcl_rx_storage::store_data (class mcl_cb *const mclcb, + du_t *du) +{ + TRACELVL(5, (mcl_stdout, + "-> mcl_rx_storage::store_data: du=x%x, seq=%d, len=%d\n", + (INT32)du, du->seq, du->len)) +#ifdef VIRTUAL_RX_MEM + if (this->vrmem_desired) { + if (this->vrmem_used == false) { + this->initialize_vrmem(); + } + if (du->vrm_info.status == STORAGE_STATUS_INVALID) { + /* new fresh DU that must be stored for the 1st time */ + if (this->vrmem->must_store_in_vrfile(mclcb, du->len)) { + if (this->vrmem->store_in_vrfile(mclcb, du) == MCL_ERROR) { + return MCL_ERROR; + } + } else { + this->vrmem->register_in_vrbuf(mclcb, du); + /* update stats */ + mclcb->stats.buf_space += du->len; + if (mclcb->stats.buf_space > mclcb->stats.max_buf_space) { + mclcb->stats.max_buf_space = + mclcb->stats.buf_space; + } + } + } else { + /* DU already stored once by the system */ + if (this->vrmem->in_vrfile(mclcb, du) && + this->vrmem->in_vrbuf(mclcb, du)) { + /* + * vrbuf copy is newer than vrfile copy, + * so update the permanent repository + * (similar to data with "dirty bit" set) + */ + if (this->vrmem->update_vrfile_from_dirty_vrbuf + (mclcb, du) == MCL_ERROR) { + return MCL_ERROR; + } + } + } + } +#else /* !VIRTUAL_RX_MEM */ + /* nothing to do, data is kept in memory and nothing is registered */ + /* update stats */ + mclcb->stats.buf_space += du->len; + if (mclcb->stats.buf_space > mclcb->stats.max_buf_space) { + mclcb->stats.max_buf_space = mclcb->stats.buf_space; + } +#endif /* VIRTUAL_RX_MEM */ + TRACELVL(5, (mcl_stdout, "<- mcl_rx_storage::store_data: du status=%d\n", + du->vrm_info.status)) + return MCL_OK; +} + + +/** + * Copies data in the buffer given in parameter, either + * from a source data buffer, or from the vrmem file, whichever + * is appropriate. + */ +mcl_error_status +mcl_rx_storage::get_data (class mcl_cb *const mclcb, + du_t *du) +{ + TRACELVL(5, (mcl_stdout, + "-> mcl_rx_storage::get_data: du=x%x, seq=%d, status=%d, len=%d\n", + (INT32)du, du->seq, du->vrm_info.status, du->len)) +#ifdef VIRTUAL_RX_MEM + if (this->vrmem_used) { + ASSERT(du->vrm_info.status != STORAGE_STATUS_INVALID); + if (this->vrmem->in_vrbuf(mclcb, du) == false) { + UINT16 symbol_len; // full size symbol length + + ASSERT(du->pkt == NULL); + ASSERT(du->data == NULL); + /* allocate destination buffer. + * Always allocate the full symbol size (needed + * by LDPC decoder, to avoid errors when adding + * the last (shorter) packet of a block). + */ + if (du->block) { + ASSERT(du->block->adu); + symbol_len = du->block->adu->symbol_len; + } else { + symbol_len = du->len; + } + mcl_rx_pkt *pkt = new mcl_rx_pkt (symbol_len); + ASSERT(pkt); + pkt->pkt_len = du->len; + du->pkt = pkt; + du->data = pkt->get_buf(); + if (symbol_len > du->len) { + memset(du->data, 0, symbol_len); + } + /* not in memory, so retrieve it from vrfile */ + if (this->vrmem->get_from_vrfile(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_rx_storage::get_data: ERROR, null buffer\n")) + return MCL_ERROR; + } + /* update stats */ + mclcb->stats.buf_space += symbol_len; + } + } +#endif /* VIRTUAL_RX_MEM */ + TRACELVL(5, (mcl_stdout, "<- mcl_rx_storage::get_data:\n")) + return MCL_OK; +} + + +/** + * Unregisters data of the DU and frees the associated data buffer. + */ +mcl_error_status +mcl_rx_storage::free_data (class mcl_cb *const mclcb, + du_t *du) +{ + TRACELVL(5, (mcl_stdout, + "-> mcl_rx_storage::free_data: du seq=%d, status=%d\n", + du->seq, du->vrm_info.status)) +#ifdef VIRTUAL_RX_MEM + /* test first if it is in vrbuf... */ + if (this->vrmem->in_vrbuf(mclcb, du) == true) { + this->vrmem->remove_from_vrbuf(mclcb, du); + /* update stats */ + mclcb->stats.buf_space -= du->len; + } + /* test now if it is also in vrfile (in this order)... */ + if (this->vrmem->in_vrfile(mclcb, du) == true) { + this->vrmem->remove_from_vrfile(mclcb, du); + } +#else + if (du->pkt) { + delete du->pkt; + du->pkt = NULL; + } + du->data = NULL; + du->len = 0; +#endif + return MCL_OK; +} + + +/** + * Initialize the Virtual receive memory service. + */ +mcl_error_status +mcl_rx_storage::initialize_vrmem () +{ + ASSERT(this->vrmem_desired == true); + ASSERT(this->vrmem_used == false); + ASSERT(this->vrmem == NULL); +#ifdef VIRTUAL_RX_MEM + this->vrmem_used = true; + this->vrmem = new mcl_vrmem; /* performs 1st level initialization */ +#else + this->vrmem_used = false; + this->vrmem = NULL; +#endif + return MCL_OK; +} + + diff --git a/src/alc/mcl_rx_storage.h b/src/alc/mcl_rx_storage.h new file mode 100644 index 0000000..a72e28e --- /dev/null +++ b/src/alc/mcl_rx_storage.h @@ -0,0 +1,294 @@ +/* $Id: mcl_rx_storage.h,v 1.5 2005/03/23 14:05:03 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_RX_STORAGE +#define MCL_RX_STORAGE + + +/** + * Class that stores all the incoming packets. + */ +class mcl_rx_pkt { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + * Allocates the data buffer with the size provided. + * @param max_size the maximum packet size, including headers + */ + mcl_rx_pkt (INT32 max_size); + + /** + * Default destructor. + * This destructor deletes both the pkt and the buffer, but NOT the DU + * (if any). + */ + ~mcl_rx_pkt (); + + /** + * Return a pointer to the buffer where the whole packet is stored. + * @return pointer to buffer. + */ + char *get_buf (); + + /** + * Return the buffer length. + * The actual size of the packet stored is lower or equal to this + * buffer size. + * @return buffer length. + */ + INT32 get_buf_len (); + + /****** Public Attributes *********************************************/ + + /** + * Return the whole packet length, including headers. + */ + INT32 pkt_len; + + +private: + /****** Private Members ***********************************************/ + + /****** Private Attributes ********************************************/ + + /** + * Buffer where packet is stored. + * This buffer is allocated once, at creation. + */ + char *buf; + + /** + * Length of this buffer. + */ + INT32 buf_len; +}; + + +/** + * Class that offers a dedicated storage service. + */ +class mcl_rx_storage { +//friend class mcl_rx_pkt; /* needed for rx_pkt to access some vrmem */ + /* methods */ + +public: + /****** Public Members ************************************************/ + + /** + * Default constructor. + */ + mcl_rx_storage(); + + /** + * Default destructor. + */ + ~mcl_rx_storage(); + + /** + * Stores data of the DU permanently, either in RAM or in the + * vrmem file, whichever is the most appropriate. + * The caller must have stored data in an rx_pkt class, associated + * to the DU. This function then either keeps data there, if enough + * space in RAM, or stores it in the vrfile and frees the rx_pkt + * class. + * @param mclcb + * @param du associated DU. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status store_data (class mcl_cb *const mclcb, + du_t *du); + +#if 0 + /** + * Stores data of the DU permanently, either in RAM or in the + * vrmem file, whichever is the most appropriate. + * The caller must have stored data in an rx_pkt class, associated + * to the DU. This function then either keeps data there, if enough + * space in RAM, or stores it in the vrfile and frees the rx_pkt + * class. + * @param mclcb + * @param du associated DU. + * @param data data of the DU that must be stored. + * @param len data length. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status store_data (class mcl_cb *const mclcb, + du_t *du, + char *data, + UINT32 len); +#endif + + /** + * Copies data of the DU in the buffer given in parameter, either + * from a source data buffer or from the vrmem file, whichever + * is appropriate. + * When needed, a new rx_pkt will be allocated and du->data set + * accordingly. + * @param mclcb + * @param du associated DU. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status get_data (class mcl_cb *const mclcb, + du_t *du); + +#if 0 + /** + * Copies data of the DU in the buffer given in parameter, either + * from a source data buffer or from the vrmem file, whichever + * is appropriate. + * @param mclcb + * @param du associated DU. + * @param buf destination buffer. + If NULL, a new rx_pkt will be allocated and du->data + set accordingly. + * @param len data length. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status get_data (class mcl_cb *const mclcb, + du_t *du, + char *data, + UINT32 len); +#endif + + /** + * Unregisters data of the DU and frees the associated data buffer. + * @param mclcb + * @param du associated DU. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status free_data (class mcl_cb *const mclcb, + du_t *du); + +#ifdef VIRTUAL_RX_MEM + /** + * Turns on or off the Virtual receive memory service. + * @param mclcb + * @param set true if vrmem is desired, false otherwise. + */ + void set_vrmem (class mcl_cb *const mclcb, + bool set); + + /** + * Is the Virtual receive memory service used? + * This does not mean that data has actually been stored in the + * vrmem file itself, just that it can be done if needed. + * @return true if the service is used, false otherwise. + */ + bool is_vrmem_used (); + + /** + * Closes the Virtual receive memory service, when applicable. + * @param mclcb + */ + void close_vrmem (class mcl_cb *const mclcb); + + /** + * Returns true if this DU is stored in the vrbuf. + * Needed for statistics purposes. + * @param mclcb + * @return true if data is in vrbuf. + */ + bool in_vrbuf (class mcl_cb *const mclcb, + struct du *du); +#endif + + + /****** Public Attributes *********************************************/ + + /** + * + * @param XXX explanation + * @return Completion status (MCL_OK or MCL_ERROR). + */ + + +private: + /****** Private Members ***********************************************/ + + /** + * Initialize the Virtual receive memory service. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status initialize_vrmem (); + + + /****** Private Attributes ********************************************/ + + /** Is the Virtual receive memory service is desired or not. */ + bool vrmem_desired; + + /** + * Indicates if the Virtual receive memory service is used or not, + * i.e. if the mcl_vrmem class has been allocated and initialized. + */ + bool vrmem_used; + +#ifdef VIRTUAL_RX_MEM + /** Virtual receive memory service class. + * Allocated/initialized only if vrmem_used is true. */ + class mcl_vrmem *vrmem; +#endif + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline char * +mcl_rx_pkt::get_buf () +{ + return this->buf; +} + +inline INT32 +mcl_rx_pkt::get_buf_len () +{ + return this->buf_len; +} + +#ifdef VIRTUAL_RX_MEM +inline void +mcl_rx_storage::set_vrmem (class mcl_cb *const mclcb, + bool set) +{ + this->vrmem_desired = set; +} + +inline bool +mcl_rx_storage::is_vrmem_used () +{ + return this->vrmem_used; +} + +inline bool +mcl_rx_storage::in_vrbuf (class mcl_cb *const mclcb, + struct du *du) +{ + return this->vrmem->in_vrbuf(mclcb, du); +} + +#endif + +#endif // MCL_RX_STORAGE diff --git a/src/alc/mcl_rx_window.cpp b/src/alc/mcl_rx_window.cpp new file mode 100644 index 0000000..daee290 --- /dev/null +++ b/src/alc/mcl_rx_window.cpp @@ -0,0 +1,542 @@ +/* $Id: mcl_rx_window.cpp,v 1.20 2005/03/23 14:05:03 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * default constructor + */ +mcl_rx_window::mcl_rx_window () +{ + memset(this, 0, sizeof(*this)); + this->delivery_mode_to_appli = MCL_IMMEDIATE_DELIVERY; + this->next_ordered_adu_to_return_toi = mcl_iss; + this->nb_of_ready_adu = 0; + this->cp2iov_fd = 0; /* must be done here, at class init */ + +} + + +/** + * default destructor + */ +mcl_rx_window::~mcl_rx_window () +{ + /* TODO: free all remaining ADUs and DUs... */ + memset(this, 0, sizeof(*this)); +} + + +/** + * Set the delivery mode. + * => See header file for more informations. + */ +mcl_error_status +mcl_rx_window::set_delivery_mode_to_appli (mcl_cb *const mclcb, + mcl_delivery_mode_to_appli mode) +{ + switch (mode) { + case MCL_IMMEDIATE_DELIVERY: + case MCL_ORDERED_DELIVERY: + break; + + default: + PRINT_ERR((mcl_stderr, + "mcl_rx_window::set_delivery_mode_to_appli: ERROR, unsupported mode %d\n", mode)) + return MCL_ERROR; + } + TRACELVL(5, (mcl_stdout, + "-> mcl_cb::set_delivery_mode_to_appli: %d", mode)) + this->delivery_mode_to_appli = mode; + return MCL_OK; +} + + +/** + * Check if all ADUs have been completed. + * => See header file for more informations. + */ +bool +mcl_rx_window::check_if_all_adu_completed (mcl_cb *const mclcb) +{ + adu_t *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_rx_window::check_if_all_adu_completed:\n")) + for (adu = this->adu_head->prev; ; adu = adu->prev) { + if (adu->rx_status < ADU_STATUS_COMPLETED) { + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::check_if_all_adu_completed: no\n")) + return false; + } + if (adu == this->adu_head) { + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::check_if_all_adu_completed: yes\n")) + return true; + } + } +} + + +/** + * Find the following ADU that can be returned to the receiving + * application, while complying with the delivery mode + * (IMMEDIATE_DELIVERY/ORDERED_DELIVERY) and FLUTE mode if applicable. + * => See header file for more informations. + */ +adu_t * +mcl_rx_window::get_next_ready_adu (mcl_cb *const mclcb) +{ + adu_t *adu, *adu_to_start_with; + + TRACELVL(5, (mcl_stdout, "-> mcl_rx_window::get_next_ready_adu:\n")) + if (this->nb_of_ready_adu <= 0) { + /* nothing ready */ + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::get_next_ready_adu: no adu available\n")) + return NULL; + } + /* first check if ADU of seq == 0 is ready */ + if ((adu = this->find_adu(mclcb, 0, -1)) != NULL) + { + if (adu->rx_status == ADU_STATUS_DECODED) { + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::get_next_ready_adu: found adu seq=%d\n", adu->seq)) + return adu; + } + } + if (this->uses_immediate_delivery_to_appli()) { + /* + * IMMEDIATE_DELIVERY + */ + /* + * there is necessarily a ready adu. + * Search by increasing seq numbers, from cache + * or from the start... + */ + if (mclcb->lastadu_cache) { + adu = mclcb->lastadu_cache; + mclcb->lastadu_cache = NULL; + } else { + adu = this->adu_head; + } + adu_to_start_with = adu; + do { + if (adu->rx_status == ADU_STATUS_DECODED) { + /* + * found a ready adu. + * it's finished, unless we are in FLUTE mode + * and this ADU is not desired + */ + if (!(mclcb->is_flute_compatible()) || + mclcb->rx_flute.is_toi_requested(mclcb, adu->seq)) { + mclcb->lastadu_cache = adu; + break; /* it's ok, done */ + } + } + adu = adu->next; + } while (adu != adu_to_start_with); /* while we haven't cycled*/ + if (adu->rx_status != ADU_STATUS_DECODED || + (mclcb->is_flute_compatible() && + !(mclcb->rx_flute.is_toi_requested(mclcb, adu->seq)))) { + /* nothing ready */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_window::get_next_ready_adu: no adu available 2\n")) + return NULL; + } + } else { + /* + * ORDERED_DELIVERY + */ + ASSERT(this->uses_ordered_delivery_to_appli()); + if ((adu = this->next_ordered_adu_to_return) || + (adu = this->find_adu(mclcb, this->next_ordered_adu_to_return_toi, 0))) { + /* the next adu to return to appli is known */ + ASSERT(adu->seq == this->next_ordered_adu_to_return_toi); + if (adu->rx_status != ADU_STATUS_DECODED) { + this->next_ordered_adu_to_return = adu; /* remember */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_window::get_next_ready_adu: next adu not ready (state=%d)\n", adu->rx_status)) + return NULL; /* not ready */ + } + if (mclcb->is_flute_compatible() && + !(mclcb->rx_flute.is_toi_requested(mclcb, adu->seq))) { + PRINT_ERR((mcl_stderr, + "<- mcl_rx_window::get_next_ready_adu: ERROR, next adu not requested by appli\n")) + return NULL; /* not requested */ + } + } + } + ASSERT(adu->rx_status == ADU_STATUS_DECODED); + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_window::get_next_ready_adu: found adu seq=%d\n", adu->seq)) + return adu; +} + + +/** + * Try to return an ADU to the appli. + * Takes into account the various delivery modes to the application, + * the FLUTE mode if applicable, and the application desires. + * This function updates everything. + * => See header file for more informations. + */ +INT32 +mcl_rx_window::return_adu_to_appli (mcl_cb *const mclcb, + struct mcl_msghdr *msg, + enum mcl_msgflag flags, + UINT32 *toi) +{ + adu_t *adu; + block_t *blk; + du_t *du; + INT32 i, j; + bool can_copy_more; /* false once appli buffers filled */ + INT32 copied; /* amount of data copied */ + struct mcl_iovec *iovec; /* base of iovec vector */ + INT32 ioveclen; /* number of entries in iovec vector */ + struct sockaddr *saddr; + INT32 saddr_len; + + TRACELVL(5, (mcl_stdout, + "-> mcl_rx_window::return_adu_to_appli: msg=x%x, flags=x%x\n", + (INT32)msg, flags)) + /* + * find a ready adu first, depending on the receiving delivery mode... + */ + adu = mclcb->rx_window.get_next_ready_adu(mclcb); + if (adu == NULL) { + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::return_adu_to_appli: no adu ready\n")) + return -1; + } + ASSERT(msg != NULL); + if (flags == MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT) { + /* it was just to check if an ADU was available... */ + ASSERT(msg->msg_iovlen == 0); + ASSERT(msg->msg_iov == NULL); + msg->toi = adu->seq; + if (toi) { + *toi = adu->seq; + } +#ifdef METAOBJECT_USED + /* check if ADU is a meta-object or if we are in meta object + * only mode */ + /* if we are do not return it */ + if ((mclcb->meta_obj_layer->metaobject_only_mode && adu->seq != 0) || + mclcb->meta_obj_layer->is_metaobj(adu->seq)) { + return -1; + } +#endif + return (adu->len); + } + iovec = msg->msg_iov; + ioveclen = msg->msg_iovlen; + if (iovec == NULL || ioveclen <= 0) { + PRINT_ERR((mcl_stderr, "mcl_rx_window::mcl_return_data_to_appli: ERROR, bad mcl_msghdr format (NULL msg_iov or msg_iovlen <= 0)\n")) + mcl_exit(-1); + } + +#ifdef METAOBJECT_USED + /* check if ADU is a meta-object or if we are in meta-object only mode*/ + /* if we are do not return it */ + if ((mclcb->meta_obj_layer->metaobject_only_mode && adu->seq != 0) || + mclcb->meta_obj_layer->is_metaobj(adu->seq)) { + return -1; + } +#endif + + /* + * then copy data... + * it requires to go through all the DUs of all the blocks of the ADU + * and all the iov buffers specified in the mcl_msghdr structure. + */ + /* initialize a context for this copy */ + if (this->init_adu_copy_to_iovec(mclcb, msg, flags) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_rx_window::mcl_return_data_to_appli: ERROR, init_adu_copy_to_iovec failed\n")) + mcl_exit(-1); + } + can_copy_more = true; + for (i = adu->blocking_struct.block_nb, blk = adu->block_head; + i > 0; i--, blk++) { + ASSERT(blk->k <= blk->du_nb_in_list); +#ifdef FEC + ASSERT(blk->fec_du_nb_in_list == 0); +#endif + for (j = blk->k, du = blk->du_head; + j > 0 && can_copy_more; + j--, du = du->next) { + /* now perform all the complex copy stuff */ + can_copy_more = this->copy_next_du_to_iovec(mclcb, du); + if (flags == MCL_MSG_DEFAULT) { + /* free this DU immediately to save space */ + mclcb->rx_storage.free_data(mclcb, du); + } + } + } + copied = this->get_amount_of_data_copied_to_iovec(mclcb); + /* + * if in MCL_MSG_DEFAULT mode, mark the adu delivered and free its + * buffers (i.e. blocks, data DUs, FEC DUs) + */ + if (flags == MCL_MSG_DEFAULT) { + mclcb->rx_window.mark_adu_delivered(adu); + //adu->remove_and_free_all_buffers(mclcb); + mcl_rx_free_this_adu(mclcb, adu); + } + /* else do nothing, next read will return the same data */ + /* + * copy source addr in application's buffer + */ + saddr = (struct sockaddr*)msg->msg_name; + saddr_len = msg->msg_namelen; + if (saddr) { + if (adu->addr.is_ipv4_addr()) { + if (saddr_len != (INT32)sizeof(struct sockaddr_in)) { + PRINT_ERR((mcl_stderr, + "mcl_rx_window::return_adu_to_appli: ERROR, addr buffer too short (%d expected for IPv4, got %d)\n", + sizeof(struct sockaddr_in), saddr_len)) + } else { + adu->addr.get_addr_struct((struct sockaddr_in*)saddr); + } + } +#ifdef INET6 + else { + if (saddr_len != (INT32)sizeof(struct sockaddr_in6)) { + PRINT_ERR((mcl_stderr, + "mcl_rx_window::return_adu_to_appli: ERROR, addr buffer too short (%d expected for IPv6, got %d)\n", + sizeof(struct sockaddr_in6), saddr_len)) + } else { + adu->addr.get_addr_struct((struct sockaddr_in6*)saddr); + } + } +#endif + } + if (toi) { + *toi = adu->seq; + } +//#if 0 + if (mclcb->get_verbosity() >= 4) { + /* dump data received, if stored in a data buffer... */ + if (msg->msg_iov->iov_type == MCL_IOV_TYPE_BUFFER && + msg->msg_iov->iov_len > 0) { + mcl_dump_buffer((char*)msg->msg_iov->iov_base, + msg->msg_iov->iov_len, + msg->msg_iov->iov_len >> 2); + } + } +//#endif + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tadu_delivered seq=%d len=%d\n", + time.tv_sec, time.tv_usec, adu->seq, adu->len)) +#ifdef GET_SYSINFO + mcl_print_sysinfo(mclcb); +#endif + } + /* + * update stats + */ + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::return_adu_to_appli: %d bytes returned\n", copied)) + return (copied); +} + + +/** + * Update nb of ready adus plus the next adu to deliver info + * (ORDERED_DELIVERY) and change the ADU status to delivered. + * => See header file for more informations. + */ +void +mcl_rx_window::mark_adu_delivered (adu_t *adu) +{ + this->nb_of_ready_adu--; + adu->rx_status = ADU_STATUS_DELIVERED; + if (adu->seq != 0) { + this->next_ordered_adu_to_return_toi++; + } + this->next_ordered_adu_to_return = NULL; // reset to avoid problems +} + + +/** + * Initialize the copy from DUs to the buffers/files specified by + * the msghdr. + * => See header file for more informations. + */ +mcl_error_status +mcl_rx_window::init_adu_copy_to_iovec (mcl_cb *const mclcb, + struct mcl_msghdr *msg, + enum mcl_msgflag flags) +{ + /* reset all context variables */ + TRACELVL(5, (mcl_stdout, " mcl_rx_window::init_adu_copy_to_iovec:\n")) + this->cp2iov_copied = 0; + this->cp2iov_msg = msg; + this->cp2iov_cur_iov = msg->msg_iov; + this->cp2iov_cur_iov_idx = 0; + if (msg->msg_iov->iov_type == MCL_IOV_TYPE_BUFFER) { + this->cp2iov_is_buffer = true; + this->cp2iov_dst = (char*)this->cp2iov_cur_iov->iov_base; + } else { + this->cp2iov_is_buffer = false; + if (this->cp2iov_cur_iov->iov_filename == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_rx_window::init_adu_copy_to_iovec: ERROR, NULL iov_filename\n")) + return MCL_ERROR; + } + if (this->cp2iov_fd != 0) { + /* if a previous fd is in use, close it... */ + mcl_file_close(this->cp2iov_fd); + } + this->cp2iov_fd = mcl_file_open( + this->cp2iov_cur_iov->iov_filename, +#ifdef WIN32 + O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, + _S_IWRITE +#else + O_WRONLY | O_CREAT | O_TRUNC, + S_IRWXU +#endif + ); + if (this->cp2iov_fd < 0) { + PRINT_ERR((mcl_stderr, + "mcl_rx_window::init_adu_copy_to_iovec: ERROR, mcl_file_open() failed for iov_filename \"%s\"\n", + this->cp2iov_cur_iov->iov_filename)) + return MCL_ERROR; + } + if (mcl_file_lseek(this->cp2iov_fd, + this->cp2iov_cur_iov->iov_offset) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_rx_window::init_adu_copy_to_iovec: ERROR, mcl_file_lseek() failed\n")) + return MCL_ERROR; + } + } + this->cp2iov_rem = this->cp2iov_cur_iov->iov_len; + return MCL_OK; +} + + +/** + * Copy an individual DU to the buffers/files specified by the msghdr. + * => See header file for more informations. + */ +bool +mcl_rx_window::copy_next_du_to_iovec (mcl_cb *const mclcb, + du_t *du) +{ + char *from; /* postiion in the source DU buffer */ + INT32 from_rem; /* remaining data to copy from the DU buffer */ + INT32 len2copy; + + /* make sure data is here... */ + if (mclcb->rx_storage.get_data(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_fec::decode(RSE): ERROR: rx_storage.get_data() failed\n")) + mcl_exit(-1); + } + /* then copy data to iovec... */ + from = du->data; + from_rem = du->len; + while (1) { + /* first copy as much as possible */ + if (this->cp2iov_rem > 0) { + len2copy = min(from_rem, this->cp2iov_rem); + if (this->cp2iov_is_buffer) { + memcpy(this->cp2iov_dst, from, len2copy); + this->cp2iov_dst += len2copy; + } else { + if (mcl_file_write(this->cp2iov_fd, from, len2copy) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_rx_window::copy_next_du_to_iovec: ERROR, mcl_file_write() failed for iov %d\n", this->cp2iov_cur_iov_idx)) + mcl_exit(-1); + } + } + this->cp2iov_rem -= len2copy; + from += len2copy; + from_rem -= len2copy; + this->cp2iov_copied += len2copy; + if (from_rem == 0) { + /* nothing else to copy */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_window::copy_next_du_to_iovec: %d bytes from DU entirely copied\n", len2copy)) + return true; + } + } + /* destination is full, so try to move to next buffer */ + this->cp2iov_cur_iov++; + this->cp2iov_cur_iov_idx++; + if (this->cp2iov_cur_iov_idx >= this->cp2iov_msg->msg_iovlen) { + /* no remaining application buffer space */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_window::copy_next_du_to_iovec: dest buffer full\n")) + return false; + } + /* can move to the following buffer */ + if (this->cp2iov_cur_iov->iov_type == MCL_IOV_TYPE_BUFFER) { + this->cp2iov_is_buffer = true; + this->cp2iov_dst = (char*)this->cp2iov_cur_iov->iov_base; + } else { + this->cp2iov_is_buffer = false; + if (this->cp2iov_cur_iov->iov_filename == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_rx_window::copy_next_du_to_iovec: ERROR, NULL iov_filename\n")) + return MCL_ERROR; + } + if (this->cp2iov_fd != 0) { + /* if a previous fd is in use, close it... */ + mcl_file_close(this->cp2iov_fd); + } + this->cp2iov_fd = mcl_file_open( + this->cp2iov_cur_iov->iov_filename, +#ifdef WIN32 + O_WRONLY | O_CREAT | O_BINARY | O_TRUNC, + _S_IWRITE +#else + O_WRONLY | O_CREAT | O_TRUNC, + S_IRWXU +#endif + ); + if (this->cp2iov_fd < 0) { + PRINT_ERR((mcl_stderr, + "mcl_rx_window::copy_next_du_to_iovec: ERROR, mcl_file_open() failed for iov_filename \"%s\"\n", + this->cp2iov_cur_iov->iov_filename)) + return MCL_ERROR; + } + if (mcl_file_lseek(this->cp2iov_fd, + this->cp2iov_cur_iov->iov_offset) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_rx_window::copy_next_du_to_iovec: ERROR, mcl_file_lseek() failed for iov %d\n", this->cp2iov_cur_iov_idx)) + mcl_exit(-1); + } + } + this->cp2iov_rem = this->cp2iov_cur_iov->iov_len; + } +} + + +/** + * Return the total amount of data copied to buffers/files since + * the previous init_adu_copy_to_iovec. + * => See header file for more informations. + */ +INT64 +mcl_rx_window::get_amount_of_data_copied_to_iovec (mcl_cb *const mclcb) +{ + return(this->cp2iov_copied); +} + diff --git a/src/alc/mcl_rx_window.h b/src/alc/mcl_rx_window.h new file mode 100644 index 0000000..2bd6099 --- /dev/null +++ b/src/alc/mcl_rx_window.h @@ -0,0 +1,360 @@ +/* $Id: mcl_rx_window.h,v 1.9 2005/01/11 13:12:33 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_RX_WINDOW_H +#define MCL_RX_WINDOW_H + + +/** + * Possible ADU delivery to the application modes. + * IMMEDIATE_DELIVERY: return an ADU to the application in arrival order + * ORDERED_DELIVERY: return an ADU to the application only if all ADUs + * with a lower TOI have already been delivered + */ +enum mcl_delivery_mode_to_appli { + MCL_IMMEDIATE_DELIVERY, + MCL_ORDERED_DELIVERY +}; + + +/** + * This class provides all the required services to manage the reception + * window at a receiver. + */ +class mcl_rx_window { + +public: + /****** Public Members ************************************************/ + /** + * default constructor + */ + mcl_rx_window (); + + /** + * default destructor + */ + ~mcl_rx_window (); + + /** + * Register a new ADU in the receiving window. + * @param mclcb + * @param adu + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status insert_adu (mcl_cb *const mclcb, + adu_t *const adu); + + /** + * Remove the ADU from the receiving window. + * @param mclcb + * @param adu + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status remove_adu (mcl_cb *const mclcb, + adu_t *const adu); + + /** + * Get the first ADU of the receiving window. + * @param mclcb + */ + adu_t *get_first_adu (mcl_cb *const mclcb); + + /** + * Get the last ADU of the receiving window. + * @param mclcb + */ + adu_t *get_last_adu (mcl_cb *const mclcb); + + /** + * Free all the ADUs of the receiving window. + * This function is only called at session close/abort. + * @param mclcb + */ + void free_all_adu (mcl_cb *const mclcb); + + /** + * Find an ADU in the receiving window with its sequence number. + * @param mclcb + * @param toi Transport Object Idf, AKA ADU seq ID + * @param FDT_instanceid associated FDT instance ID if it + is an FDT (i.e. toi == 0) (FLUTE specific) + * @return returns a pointer to the adu if found, NULL otherwise + */ + adu_t *find_adu (mcl_cb *const mclcb, + UINT32 toi, + INT32 FDT_instanceid); + + /** + * Check if all ADUs have been completed. + * @param mclcb + * @return boolean + */ + bool check_if_all_adu_completed (mcl_cb *const mclcb); + + /** + * Note that a new ADU is ready. + */ + void mark_ready_adu (); + + /** + * Is there an ADU ready to be returned to the appli? + */ + bool is_an_adu_ready (); + + /** + * Find the following ADU that can be returned to the receiving + * application, while complying with the delivery mode + * (IMMEDIATE_DELIVERY/ORDERED_DELIVERY) and FLUTE mode if applicable. + * Warning, this function is read-only and does not change anything + * in the rx_window list nor does it mark the ADU as delivered! + * @param mclcb + * @return next ADU fully received and decoded, complying with the + * delivery mode, NULL otherwise. + */ + adu_t *get_next_ready_adu (mcl_cb *const mclcb); + + /** + * Try to return an ADU to the appli. + * Takes into account the various delivery modes to the application, + * the FLUTE mode if applicable, and the application desires. + * This function updates everything. + * @param mclcb + * @param msg + * @param flags + * @param toi pointer to variable which will contain the TOI upon + * return (FLUTE and Meta-object specific). + * @return the amount (> 0) of data copied to the buffers/files + * specified by msg (unless + * MCL_MSG_CHECK_IF_DATA_IS_AVAILABLE is set in flags in + * which case nothing is copied), or < 0 if no data is + * available. + */ + INT32 return_adu_to_appli (mcl_cb *const mclcb, + struct mcl_msghdr *msg, + enum mcl_msgflag flags, + UINT32 *toi); + + /** + * Update the nb of ready adus (plus the next adu to deliver info + * in ORDERED_DELIVERY mode), and change the ADU status to delivered. + */ + void mark_adu_delivered (adu_t *adu); + + /** + * Does the receiver use an immediate delivery mode. + * @return boolean + */ + bool uses_immediate_delivery_to_appli (void); + + /** + * Does the receiver use an ordered delivery mode. + * @return boolean + */ + bool uses_ordered_delivery_to_appli (void); + + /** + * Set the ADU delivery mode to the application. + * @param mclcb + * @param mode delivery mode to set + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_delivery_mode_to_appli + (mcl_cb *const mclcb, + mcl_delivery_mode_to_appli mode); + + /** + * Get the ADU delivery mode to the application. + * @param mclcb + * @return delivery mode + */ + mcl_delivery_mode_to_appli get_delivery_mode_to_appli + (mcl_cb *const mclcb); + + + /****** Public Attributes *********************************************/ + + /** + * Is RSE decoding performed progressively or at the very end? + */ + bool postpone_fec_decoding; + + +private: + /****** Private Members ***********************************************/ + + /** + * Initialize the copy from DUs to the buffers/files specified by + * the msghdr. Creates a context. Be careful, this function is not + * re-entrant. + * @param mclcb + * @param msg Message control struct used by mcl_sndmsg/mcl_recvmsg. + * @param flags Flags used by mcl_sndmsg/mcl_recvmsg. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status init_adu_copy_to_iovec + (mcl_cb *const mclcb, + struct mcl_msghdr *msg, + enum mcl_msgflag flags); + + /** + * Copy an individual DU to the buffers/files specified by the msghdr. + * @param mclcb + * @param du + * @return true if there is some more room in the destination + * buffers/files, false otherwise. + */ + bool copy_next_du_to_iovec (mcl_cb *const mclcb, + du_t *du); + + /** + * Return the total amount of data copied to buffers/files since + * the previous init_adu_copy_to_iovec. + * @param mclcb + * @return total number of data copied. + */ + INT64 get_amount_of_data_copied_to_iovec (mcl_cb *const mclcb); + + + /****** Private Attributes ********************************************/ + /** Head of ADU doubly linked list. */ + adu_t *adu_head; + + /** Number of ADUs been fully decoded and can be sent to the appli */ + UINT32 nb_of_ready_adu; + + /** Next ADU to return in case of an ORDERED_DELIVERY. */ + adu_t *next_ordered_adu_to_return; + /** TOI of next ADU to return in case of an ORDERED_DELIVERY. */ + UINT32 next_ordered_adu_to_return_toi; + + /* Immediate vs ordered_delivery of ADUs to the receiving appli. */ + mcl_delivery_mode_to_appli delivery_mode_to_appli; + + + /* + * Copy to iovec service. + */ + /** Amount of data already copied */ + INT64 cp2iov_copied; + + /** True if dest is a buffer, false if dest is a file. */ + bool cp2iov_is_buffer; + + /** Destination ptr in buffer. Does not necessarily point to start. + * Only valid if cp2iov_is_buffer is true */ + char *cp2iov_dst; + + /** Destination file descriptor. */ + INT32 cp2iov_fd; + +#if 0 + /** Offset in destination file. */ + INT64 cp2iov_offset; +#endif + + /** Remaining size in destination area for the current iovec entry. */ + INT64 cp2iov_rem; + + /** Source msghdr struct. */ + struct mcl_msghdr *cp2iov_msg; + + /** Current iovec in the iovec vector. */ + struct mcl_iovec *cp2iov_cur_iov; + + /** Current iovec index in the iovec vector. */ + INT32 cp2iov_cur_iov_idx; +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline mcl_error_status +mcl_rx_window::insert_adu (mcl_cb *const mclcb, + adu_t *const adu) +{ + mcl_insert_adu(mclcb, adu, &(this->adu_head)); + return MCL_OK; + //return adu->insert_in_list(mclcb, &(this->adu_head)); +} + +inline mcl_error_status +mcl_rx_window::remove_adu (mcl_cb *const mclcb, + adu_t *const adu) +{ + mcl_remove_adu(mclcb, adu, &(this->adu_head)); + return MCL_OK; + //return adu->remove_from_list(mclcb, &(this->adu_head)); +} + +inline adu_t * +mcl_rx_window::find_adu (mcl_cb *const mclcb, + UINT32 toi, + INT32 FDT_instanceid) +{ + return (mcl_find_adu(mclcb, toi, FDT_instanceid, this->adu_head)); + //return this->adu_head->find_in_list(mclcb, this->adu_head, toi); +} + +inline adu_t * +mcl_rx_window::get_first_adu (mcl_cb *const mclcb) +{ + return this->adu_head; +} + +inline adu_t * +mcl_rx_window::get_last_adu (mcl_cb *const mclcb) +{ + return ((this->adu_head != NULL) ? this->adu_head->prev : NULL); +} + +inline void +mcl_rx_window::mark_ready_adu() +{ + nb_of_ready_adu++; +} + +inline bool +mcl_rx_window::is_an_adu_ready () +{ + return (nb_of_ready_adu > 0); +} + +inline bool +mcl_rx_window::uses_immediate_delivery_to_appli () +{ + return (this->delivery_mode_to_appli == MCL_IMMEDIATE_DELIVERY); +} + +inline bool +mcl_rx_window::uses_ordered_delivery_to_appli () +{ + return (this->delivery_mode_to_appli == MCL_ORDERED_DELIVERY); +} + +inline mcl_delivery_mode_to_appli +mcl_rx_window::get_delivery_mode_to_appli (mcl_cb *const mclcb) +{ + return this->delivery_mode_to_appli; +} + +#endif // MCL_RX_WINDOW_H diff --git a/src/alc/mcl_sched.cpp b/src/alc/mcl_sched.cpp new file mode 100644 index 0000000..785f325 --- /dev/null +++ b/src/alc/mcl_sched.cpp @@ -0,0 +1,568 @@ +/* $Id: mcl_sched.cpp,v 1.12 2005/05/23 11:11:50 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * Transmission plannification for each new ADU. + */ + +#include "mcl_includes.h" + + +/* + * Create the sending tx planning after receiving a new ADU. + * Called by the sending function of the lib. + * NB: not implemented with processing speed in mind! + */ + + +#ifdef LCT_SCHED1 +static void LCT1_UpdateTxPlanning (mcl_cb *mclcb, adu_t *adu_start, + adu_t *adu_end); +#endif +#ifdef LCT_SCHED2 +static void LCT2_UpdateTxPlanning (mcl_cb *mclcb, adu_t *adu_start, + adu_t *adu_end); +#endif +#ifdef LCT_SCHED3 +static void LCT3_UpdateTxPlanning (mcl_cb *mclcb, adu_t *adu_start, + adu_t *adu_end); +#endif + + +/* + * scheduler switching table + */ +typedef void (*UpdateTxPlanning_func) (mcl_cb *mclcb, adu_t *adu_start, adu_t *adu_end); +static UpdateTxPlanning_func sched_tab[MCL_SCHED_NB]; + + +/****** LCT scheduling common functions ***************************************/ + + +/* + * switch according to the scheduler in use + */ +void UpdateTxPlanning (mcl_cb *mclcb, + adu_t *adu_start, + adu_t *adu_end) +{ + static int initialized = 0; + + ASSERT(adu_start && adu_end); + if (!initialized) { +#ifdef LCT_SCHED1 + sched_tab[MCL_SCHED_LCT1] = LCT1_UpdateTxPlanning; +#endif +#ifdef LCT_SCHED2 + sched_tab[MCL_SCHED_LCT2] = LCT2_UpdateTxPlanning; +#endif +#ifdef LCT_SCHED3 + sched_tab[MCL_SCHED_LCT3] = LCT3_UpdateTxPlanning; +#endif + initialized = 1; + } + ASSERT(sched_tab[mclcb->scheduler]); + sched_tab[mclcb->scheduler](mclcb, adu_start, adu_end); +} + + +/* + * Create a random permutation of (1..n) + * (see: http://www.cs.berkeley.edu/~jfc/cs174/lecs/lec2.html) + * Returns a table containing the random permutation. + * WARNING: it is the caller's responsibility to free + * this array. + */ +#define mcl_random_permut(a,n) mcl_pseudorandom_permut((a),(n),1) + +/* + * create a partially random permutation of (1..n) + */ +static void +mcl_pseudorandom_permut (int *a, /* input/output array */ + int n, /* number of elements in array */ + int l) /* permut one elt out of l */ +{ + int i, j, temp; + + ASSERT(l <= n); + for (i = 0; i < n; i++) + a[i] = i; + for (i = 0; i < n; i+=l) { /* skip some indexes */ + j = random() % n; + temp = a[i]; + a[i] = a[j]; + a[j] = temp; + } +} + + +/****** LCT scheduling version 1 **********************************************/ +#if defined(LCT_SCHED1) /* { */ + + +/* + * struct used to identify ADUs given a DU index + */ +typedef struct { + adu_t *adu; /* for this ADU */ + int first_idx; /* DUs start at this (flat) index... */ + int last_idx; /* ... up to this one */ + int du_nb; /* total nb of data DUs in all blocks */ + /* fields required by LCT_SCHED2 */ + int nb_fec_layers; /* nb of FEC layers in LCT_SCHED2 */ +} idx_range_t; + + +/* binary search more efficient with sessions having very large number of ADU */ +#define BIN_SEARCH + +#ifdef BIN_SEARCH +/* + * binary tree search version... + * usefull in case of very large ADU sessions + */ +static int +mcl_flat_index_to_adu_bsearch (idx_range_t *idx_range_tab, + int low, /* low index, included */ + int high, /* high index, included */ + int index) +{ + int mid; /* mid index */ + ASSERT(low <= high); + /*if (low == high) { return low; }*/ + mid = ((low + high) >> 1); + if (index <= idx_range_tab[mid].last_idx) { + if (index >= idx_range_tab[mid].first_idx) + return mid; /* found */ + return mcl_flat_index_to_adu_bsearch(idx_range_tab, low, mid, + index); + } else { + return mcl_flat_index_to_adu_bsearch(idx_range_tab, mid+1, high, + index); + } +} + + +/* + * retrieve the idx_range_t struct of the adu corresponding to the flat + * index given. + */ +#ifdef DEBUG +static idx_range_t* +mcl_flat_index_to_adu (mcl_cb *mclcb, + idx_range_t *idx_range_tab, + int nb_entries, + int index) +{ + int idx; + ASSERT(index >= 0 && index <= idx_range_tab[nb_entries-1].last_idx); + idx = mcl_flat_index_to_adu_bsearch (idx_range_tab, 0, + nb_entries-1, index); + TRACELVL(5, (mcl_stdout, + " mcl_flat_index_to_adu: index=%d, adu=x%x\n", + index, (int)idx_range_tab[idx].adu)) + return &(idx_range_tab[idx]); +} +#else /* DEBUG */ +#define mcl_flat_index_to_adu(mclcb,idx_range_tab,nb_entries,index) \ + &(idx_range_tab[mcl_flat_index_to_adu_bsearch(idx_range_tab, 0, \ + (nb_entries)-1, (index))]) +#endif /* DEBUG */ + + +#else /* BIN_SEARCH */ + + +/* + * retrieve the idx_range_t struct of the adu corresponding to the flat + * index given. + */ +static idx_range_t* +mcl_flat_index_to_adu (mcl_cb *mclcb, + idx_range_t *idx_range, + int nb_entries, + int index) +{ + /*TRACELVL(5, (mcl_stdout, "-> mcl_flat_index_to_adu: index=%d\n", index))*/ + ASSERT(index >= 0); + while (1) { + ASSERT(idx_range->adu != NULL); + if (index <= idx_range->last_idx && /* more efficient */ + index >= idx_range->first_idx) { /* in this order! */ + /* found */ + TRACELVL(5, (mcl_stdout, " mcl_flat_index_to_adu: idx=%d, adu=x%x\n", + index, (int)idx_range->adu)); + return idx_range; + } + idx_range++; + } + ASSERT(0); /* unreachable */ + return NULL; +} + + +#endif /* BIN_SEARCH */ + + +static int LCT1_mcl_get_tot_nb_of_du (mcl_cb *mclcb, adu_t *adu); +static du_t* LCT1_mcl_flat_index_to_du (mcl_cb *mclcb, adu_t *adu, int index); + + +/* + * Send everything on each layer. + * Currently uses a straightforward algorithm: all the DUs are sent + * on all the layers using a random permutation + */ +void +LCT1_UpdateTxPlanning (mcl_cb *mclcb, + adu_t *adu_start, /* first ADU (included) */ + adu_t *adu_end) /* last ADU (included) */ +{ + int i; /* */ + int j; /* flat index in random permutation array */ + int lay; /* layer nb */ + txlay_t *tl; + int *permut; /* random permutation array */ + int adu_nb; /* number of ADUs */ + adu_t *adu; + int du_nb; /* number of DUs */ + int tot_du_nb; /* total DU nb (incl. FEC) for all blks, all ADUs */ + du_t *du; + idx_range_t *idx_range; /* table */ + + TRACELVL(5, (mcl_stdout, "-> LCT1_UpdateTxPlanning:\n")) + if (adu_start == adu_end) { + /* the easy traditional case: only one adu */ + /* + * tot_du_nb includes both plain DUs and FEC DUs of all blocks + */ + TRACELVL(5, (mcl_stdout, " LCT1_UpdateTxPlanning: LCT org1/sequential object order\n")) + adu = adu_start; + tot_du_nb = LCT1_mcl_get_tot_nb_of_du(mclcb, adu); + if (!(permut = (int*)malloc(tot_du_nb * sizeof(int)))) { + goto no_memory; + } + /* + * for each layer, create a random permutation of all the DUs + * and register them + */ + for (lay = 0, tl = mclcb->txlay_tab; lay < mclcb->max_nb_layers; + lay++, tl++) { + mcl_random_permut(permut, tot_du_nb); + ASSERT(permut); + for (j = 0; j < tot_du_nb; j++) { + du = LCT1_mcl_flat_index_to_du(mclcb, adu, permut[j]); + ASSERT(du); +#ifdef VIRTUAL_TX_MEM + du->vtm_info.du_in_seq_in_txtab = 1; +#endif + if (du->block->adu->priority == ADU_NORMAL_PRIO) { + tl->tx_tab->register_du(mclcb, du, + mclcb->nb_tx); + } else { + ASSERT(du->block->adu->priority == ADU_HIGH_PRIO); + tl->tx_tab_high->register_du(mclcb, du, + mclcb->nb_tx); + } + + } + } + } else if (mclcb->adu_scheduling == MCL_SCHED_RANDOM_OBJ_ORDER) { + /* a bit more complex: list of adus */ + /* + * send ADUs in a different random order on each layer + */ + int *permut2; /* random DU permutation array*/ + idx_range_t *ir; /* table */ + int max_du_nb; /* max number of DUs in ADUs */ + + TRACELVL(5, (mcl_stdout, + " LCT1_UpdateTxPlanning: LCT org1/random obj order\n")) + adu_nb = adu_end->seq - adu_start->seq + 1; + if (!(permut = (int*)malloc(adu_nb * sizeof(int))) || + !(idx_range = (idx_range_t *)malloc(adu_nb * sizeof(idx_range_t)))) { + goto no_memory; + } + max_du_nb = -1; + for (i = 0, adu = adu_start, ir = idx_range; + i < adu_nb; + i++, adu = adu->next, ir++) { + ir->du_nb = LCT1_mcl_get_tot_nb_of_du(mclcb, adu); + if (ir->du_nb > max_du_nb) + max_du_nb = ir->du_nb; + ir->adu = adu; + ir->first_idx = 0; /* register adu id only */ + ir->last_idx = 0; /* register adu id only */ + } + /* allocate this tab only once */ + if (!(permut2 = (int*)malloc(max_du_nb * sizeof(int)))) { + goto no_memory; + } + /* + * for each layer, create a random permutation of all the ADUs + * and then a random permutation of all the DUs for each ADU. + */ + for (lay = 0, tl = mclcb->txlay_tab; lay < mclcb->max_nb_layers; + lay++, tl++) { + mcl_random_permut(permut, adu_nb); + for (i = 0; i < adu_nb; i++) { + adu = idx_range[permut[i]].adu; + du_nb = idx_range[permut[i]].du_nb; + mcl_random_permut(permut2, du_nb); + for (j = 0; j < du_nb; j++) { + du = LCT1_mcl_flat_index_to_du(mclcb, + adu, permut2[j]); + ASSERT(du); +#ifdef VIRTUAL_TX_MEM + du->vtm_info.du_in_seq_in_txtab = 1; +#endif + if (du->block->adu->priority == ADU_NORMAL_PRIO) { + tl->tx_tab->register_du(mclcb, + du, mclcb->nb_tx); + } else { + ASSERT(du->block->adu->priority == ADU_HIGH_PRIO); + tl->tx_tab_high->register_du(mclcb, + du, mclcb->nb_tx); + } + } + } + } + } else { + /* a bit more complex: list of adus */ + /* + * mix everything: all the DUs of all the ADUs are sent + * on all the layers using a random permutation + */ + /* + * how many DUs per ADU; remember it for future index->du access + */ + idx_range_t *idx_entry; + int idx; /* index */ + + TRACELVL(5, (mcl_stdout, " LCT1_UpdateTxPlanning: LCT org1/mixed order\n")) + adu_nb = adu_end->seq - adu_start->seq + 1; + if (!(idx_range = (idx_range_t *)malloc(adu_nb * sizeof(idx_range_t)))) { + goto no_memory; + } + tot_du_nb = 0; + for (i = 0, adu = adu_start; i < adu_nb; i++, adu = adu->next) { + du_nb = LCT1_mcl_get_tot_nb_of_du(mclcb, adu); + idx_range[i].adu = adu; + idx_range[i].first_idx = tot_du_nb; + tot_du_nb += du_nb; + idx_range[i].last_idx = tot_du_nb - 1; + } + if (!(permut = (int*)malloc(tot_du_nb * sizeof(int)))) { + goto no_memory; + } + /* + * for each layer, create a random permutation of all the DUs + * and register them + */ + for (lay = 0, tl = mclcb->txlay_tab; lay < mclcb->max_nb_layers; + lay++, tl++) { + /*mcl_random_permut(permut, tot_du_nb);*/ + if (mclcb->adu_scheduling == MCL_SCHED_MIXED_ORDER) { + mcl_random_permut(permut, tot_du_nb); + } else if (mclcb->adu_scheduling == MCL_SCHED_PARTIALLY_MIXED_ORDER) { + /* + * if you want you can change the spacing parameter + * to modify the probability for a DU not to be + * permutted. The higher the value, the less random! + */ + mcl_pseudorandom_permut(permut, tot_du_nb, 2); + } else { + PRINT_ERR((mcl_stderr, "LCT1_UpdateTxPlanning: ERROR, ADU scheduler %d not possible in LCT1\n", mclcb->adu_scheduling)) + mcl_exit(-1); + } + ASSERT(permut); + for (j = 0; j < tot_du_nb; j++) { + idx_entry = mcl_flat_index_to_adu(mclcb, + idx_range, adu_nb, permut[j]); + adu = idx_entry->adu; + idx = permut[j] - idx_entry->first_idx; + ASSERT(idx >= 0); + ASSERT(adu); + du = LCT1_mcl_flat_index_to_du(mclcb, adu, idx); + ASSERT(du); +#ifdef VIRTUAL_TX_MEM + du->vtm_info.du_in_seq_in_txtab = 1; +#endif + if (du->block->adu->priority == ADU_NORMAL_PRIO) { + tl->tx_tab->register_du(mclcb, du, + mclcb->nb_tx); + } else { + ASSERT(du->block->adu->priority == ADU_HIGH_PRIO); + tl->tx_tab_high->register_du(mclcb, du, + mclcb->nb_tx); + } + } + } + free(idx_range); + } + free(permut); + TRACELVL(5, (mcl_stdout, "<- LCT1_UpdateTxPlanning:\n")) + return; + +no_memory: + PRINT_ERR((mcl_stderr, "LCT1_UpdateTxPlanning: ERROR, no memory")) + mcl_exit(-1); +} + + +static int +LCT1_mcl_get_tot_nb_of_du (mcl_cb *mclcb, + adu_t *adu) +{ + int i; + block_t *blk; + int nb = 0; + + /*TRACELVL(5, (mcl_stdout, "-> LCT1_mcl_get_tot_nb_of_du:\n"))*/ + for (i = adu->blocking_struct.block_nb, blk = adu->block_head; i > 0; i--, blk++) { + nb += blk->k; +#ifdef FEC + nb += blk->fec_du_nb_in_list; +#endif + } + TRACELVL(5, (mcl_stdout, " LCT1_mcl_get_tot_nb_of_du: %d du\n", nb)) + return nb; +} + + +/* + * retrieve the du corresponding to the (flat) index given. + */ +static du_t* +LCT1_mcl_flat_index_to_du (mcl_cb *mclcb, + adu_t *adu, + int index) +{ + int i; + block_t *blk; + + /*TRACELVL(5, (mcl_stdout, "-> LCT1_mcl_flat_index_to_du: index=%d\n", index))*/ + ASSERT(index >= 0); + ASSERT(index < LCT1_mcl_get_tot_nb_of_du(mclcb, adu)); + for (i = adu->blocking_struct.block_nb, blk = adu->block_head; + i > 0; i--, blk++) { + if (index < (int)blk->k) { + TRACELVL(5, (mcl_stdout, + " LCT1_mcl_flat_index_to_du: idx=%d, du=x%x\n", + index, (int)&(blk->du_head[index]))) + return &(blk->du_head[index]); + } + index -= blk->k; +#ifdef FEC + if (index < (int)blk->fec_du_nb_in_list) { + TRACELVL(5, (mcl_stdout, + " LCT1_mcl_flat_index_to_du: fec idx=%d, du=x%x\n", + index, (int)&(blk->du_head[index]))) + return &(blk->fec_du_head[index]); + } + index -= blk->fec_du_nb_in_list; +#endif + } + ASSERT(0); /* unreachable */ + return NULL; +} + + +#endif /* } */ + + +/****** LCT scheduling for ANTICIPATED_TX_FOR_PUSH ****************************/ +#if defined(ANTICIPATED_TX_FOR_PUSH) /* { */ + + +static void AnticipTx_register_du_on_right_layer (mcl_cb *mclcb, du_t *du); + + +/* + * Create a linear and vertical scheduling of DUs, i.e. accross all layers. + * Always called with a single adu. + * No FEC transmission, only data. + * No randomization here, linear scheduling. + */ +void +AnticipTx_UpdateTxPlanning (mcl_cb *mclcb, + adu_t *adu) +{ + block_t *blk; + int b_nb; /* nb of blocks */ + int du_nb; /* nb of dus */ + du_t *du; + + TRACELVL(5, (mcl_stdout, "-> AnticipTx_UpdateTxPlanning:\n")) + /* + * register all the data DUs of this ADU + */ + for (b_nb = adu->blocking_struct.block_nb, blk = adu->block_head; + b_nb > 0; b_nb--, blk++) { + for (du_nb = blk->k, du = blk->du_head; du_nb > 0; + du_nb--, du++) { + AnticipTx_register_du_on_right_layer(mclcb, du); + } + } + TRACELVL(5, (mcl_stdout, "<- AnticipTx_UpdateTxPlanning:\n")) +} + + +static void +AnticipTx_register_du_on_right_layer (mcl_cb *mclcb, + du_t *du) +{ + static int layer = 0; /* next tx is on that layer */ + static int rem_2_tx_on_layer = 1; /* can send that nb of du */ + + TRACELVL(5, (mcl_stdout, + " AnticipTx_register_du_on_right_layer: lay=%d, rem2tx=%d\n", + layer, rem_2_tx_on_layer)) + if (rem_2_tx_on_layer <= 0) { + /* move to next layer */ + /* only consider first 5 or max_nb_layers layers */ + if (++layer >= mclcb->max_nb_layers || layer >= 5) + layer = 0; + /* + * consider the upper integer, to avoid rounding to 0 + * with very low bit rates... This is not fully accurate, + * but we don't care in this particular case. + */ + rem_2_tx_on_layer = (INT32)ceil(mclcb->txlay_tab[layer].du_per_tick); + } + /* schedule for a SINGLE tx */ +#ifdef VIRTUAL_TX_MEM + du->vtm_info.du_in_seq_in_txtab = 1; +#endif + if (du->block->adu->priority == ADU_NORMAL_PRIO) { + mclcb->txlay_tab[layer].tx_tab->register_du(mclcb, du, 1); + } else { + ASSERT(du->block->adu->priority == ADU_HIGH_PRIO); + mclcb->txlay_tab[layer].tx_tab_high->register_du(mclcb, du, 1); + } + rem_2_tx_on_layer--; + /*TRACELVL(5, (mcl_stdout, "<- AnticipTx_register_du_on_right_layer: layer=%d\n", layer))*/ +} + + +#endif /* ANTICIPATED_TX_FOR_PUSH } */ + diff --git a/src/alc/mcl_sig.cpp b/src/alc/mcl_sig.cpp new file mode 100644 index 0000000..ecfc2e7 --- /dev/null +++ b/src/alc/mcl_sig.cpp @@ -0,0 +1,399 @@ +/* $Id: mcl_sig.cpp,v 1.7 2005/01/11 13:12:34 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * signaling functions. + */ + +#include "mcl_includes.h" + + +/* private function */ +static int SendSigPacket (mcl_cb *mclcb, int type, char *buf, int len); +static void mcl_sig_initialize (mcl_cb *mclcb); + +/* + * private variables + */ +static int initialized = 0; +/* WARNING!: keep it coherent with each signaling type (mcl_alc/lct_hdr.h) */ +static short max_tx_times[SIG_CLOSE+1]; + + +/* + * high-level SIG sending routines + */ +int +SendNONEWADU (mcl_cb *mclcb, + int max_adu) /* last ADU to be sent */ +{ + int *ptr; + int err; + + TRACELVL(5, (mcl_stdout, "-> SendNONEWADU: max_adu=%d\n", max_adu)) + if (mclcb->get_verbosity() >= 1) + PRINT_OUT((mcl_stdout, "Send_NONEWADU\n")) + if (!(ptr = (int*)malloc(sizeof(int)))) { + PRINT_ERR((mcl_stderr, "SendNONEWADU: ERROR, no memory")) + mcl_exit(-1); + } + *ptr = max_adu; + /* 8 bytes required by EXT_NONEWADU EH, cf mcl_alc_hdr.c */ + err = SendSigPacket(mclcb, EXT_NONEWADU, (char*)ptr, 8); + if (mclcb->get_stats_level() > 0) + mcl_print_tx_stats(mclcb); + TRACELVL(5, (mcl_stdout, "<- SendNONEWADU:\n")) + return err; +} + + +int +SendCLOSE (mcl_cb *mclcb) +{ + int err; + + TRACELVL(5, (mcl_stdout, "-> SendCLOSE:\n")) +#ifdef NEVERDEF + /* for tests only: check rx FSM if no CLOSE received */ + if (mclcb->get_verbosity() >= 1) + PRINT_OUT((mcl_stdout, "SendCLOSE deleted!!!\n")) +#else + if (mclcb->get_verbosity() >= 1) + PRINT_OUT((mcl_stdout, "Send_CLOSE\n")) + /* 4 bytes required by SIG_CLOSE EH, cf mcl_alc_hdr.c/mcl_lct_hdr.c */ + err = SendSigPacket(mclcb, SIG_CLOSE, (char*)NULL, 4); + if (mclcb->get_stats_level() > 0) + mcl_print_tx_stats(mclcb); +#endif /* NEVERDEF */ + TRACELVL(5, (mcl_stdout, "<- SendCLOSE:\n")) + return err; +} + + +/****** SIG manipulation functions ******/ + + +/* + * Add a SIG to the sig_tab. + * Return 0 if OK, an error code otherwise. + */ +int +AddSigToTab (mcl_cb *mclcb, + sig_tab_t *new_sig) +{ + TRACELVL(5, (mcl_stdout, "-> AddSigToTab:\n")) + /* insert new sig at the begining of list */ + if (mclcb->sig_tab == NULL) { + new_sig->next = NULL; + mclcb->sig_tab = new_sig; + } else { + /* insert at end; this is preferable for NONEWADU, CLOSE... */ + sig_tab_t *psig; + for (psig = mclcb->sig_tab; psig->next != NULL; + psig = psig->next); + new_sig->next = NULL; + psig->next = new_sig; + } + mclcb->mcl_sig_pending++; + TRACELVL(5, (mcl_stdout, "<- AddSigToTab:\n")) + return 0; +} + + +/* + * Remove a particular sig message from the sig_tab table + * Returns 1 if removed, 0 otherwise + */ +int +RemSigFromTab (mcl_cb *mclcb, + int level, /* level concerned by this sig hdr */ + int type, /* type of signaling */ + int ext_type) +{ +#if !defined(ALC) + sig_tab_t *psig; + + TRACELVL(5, (mcl_stdout, "-> RemSigFromTab: level=%d, type=%d, ext_type=%d\n", + level, type, ext_type)) + for (psig = mclcb->sig_tab; psig ; psig = psig->next) { + if (psig->target_lvl != level || psig->eh_type != type) + continue; + switch (type) { + case EH_SIG: { + sig_hdr_t *ph = (sig_hdr_t*)psig->buf; + if (ph && ph->type == ext_type) + goto found; + break; + } + } + } + TRACELVL(5, (mcl_stdout, "<- RemSigFromTab: none\n")) + return 0; +found: + psig->rem2send = 0; + CleanupSigTab(mclcb); + TRACELVL(5, (mcl_stdout, "<- RemSigFromTab: removed\n")) + return 1; +#else + return 0; +#endif /* !ALC */ +} + + +/* + * Required before a calling CopySigToBuf repetedly in mcl_send_pkt + */ +void +CopySigReset(mcl_cb *mclcb) +{ + mclcb->skip = 0; + mclcb->psig_next = mclcb->sig_tab; +} + + +/* + * Return 1 if there remains some SIG ready to be tx for THIS + * layer, 0 otherwise. + */ +int +CanCopyMoreSig (mcl_cb *mclcb, + int level) +{ + sig_tab_t *psig; + + for (psig = mclcb->psig_next; psig ; psig = psig->next) { + if (psig->target_lvl == level || psig->target_lvl == -1) { + /* found at least one */ + return 1; + } + } + return 0; +} + + +/* + * Prepar the copy a given numbers of SIG from the sig_tab but + * skip the first ones. + * Returns the number of SIG copied if OK, < 0 otherwise. + */ +int +CopySigToLCTinfos (mcl_cb *mclcb, + int level, /* send pkt here */ + hdr_infos_t *hdr_infos, /* where to copy */ + int len) /* available size for new SIG */ +{ + int nb = 0; /* # of SIG written */ + int sz = 0; /* total size written to buf */ + sig_tab_t *psig; + + TRACELVL(5, (mcl_stdout, "-> CopySigToLCTinfos:\n")) + ASSERT(level >= 0); + /* + * copy as many SIG as possible + * NB: check before that the pending sig's target level is the + * right one + */ + for (psig = mclcb->psig_next; psig ; + mclcb->psig_next = psig = psig->next, mclcb->skip++) { + if (psig->target_lvl != level && psig->target_lvl != -1) { + /* not the right target level! skip it... */ + TRACELVL(5, (mcl_stdout, " CopySigToLCTinfos: bad layer for sig %d (%d, expected %d)\n", + psig->eh_type, level, psig->target_lvl)) + continue; + } + if (psig->rem2send == 0) { + /* not yet cleaned ! skip it... */ + continue; + } + if (sz + psig->len > len) { + /* can't add any more (no room)! keep it for next time*/ + TRACELVL(5, (mcl_stdout, " CopySigToLCTinfos: no room for sig %d (%d, expected %d)\n", + psig->eh_type, len, sz + psig->len)) + //ASSERT(psig->len < MAX_UNFRAG_DATAGRAM_SZ); + ASSERT(psig->len < MAX_DATAGRAM_SIZE); + break; + } + switch (psig->eh_type) { + case EXT_NONEWADU: + hdr_infos->NONEWADU_present = true; + hdr_infos->max_idf_adu = *(int*)psig->buf; + break; + + case SIG_CLOSE: + hdr_infos->close = true; + break; + default: + break; + } + TRACELVL(5, (mcl_stdout, " CopySigToLCTinfos: sig %d added\n", + psig->eh_type)) + sz += psig->len; + nb++; + if (psig->rem2send > 0) + psig->rem2send--; + } + TRACELVL(5, (mcl_stdout, "<- CopySigToLCTinfos: nb=%d\n", nb)) + return nb; +} + + +/* + * Withdraw all the SIG sent a sufficient number of times from the sig_tab. + * Return 0 if OK, an error code otherwise. + */ +int +CleanupSigTab (mcl_cb *mclcb) +{ + sig_tab_t *psig, + *prev; + + TRACELVL(5, (mcl_stdout, "-> CleanupSigTab:\n")) + for (psig = mclcb->sig_tab, prev = NULL; psig != NULL; ) { + /* + * if psig->rem2send < 0 then tx for ever + * else if == 0, remove it, + * else if > 0, keep it. + */ + if (psig->rem2send == 0) { + free(psig->buf); + if (psig->saddr && psig->saddr_len > 0) + free(psig->saddr); + if (psig == mclcb->sig_tab) { + mclcb->sig_tab = psig->next; + free(psig); + psig = mclcb->sig_tab; + } else { + ASSERT(prev) + prev->next = psig->next; + free(psig); + psig = prev->next; + } + mclcb->mcl_sig_pending--; + } else { + prev = psig; + psig = psig->next; + } + } + TRACELVL(5, (mcl_stdout, "<- CleanupSigTab:\n")) + return 0; +} + + +/* + * Send a signaling message. + * Depending on the packet type, this may happen either in a future + * data packet or immediately (e.g. with EXT_NONEWADU, SIG_CLOSE). + */ +static int +SendSigPacket (mcl_cb *mclcb, + int type, + char *buf, + int len) +{ + sig_tab_t *new_sig; + int tmp_rem2send; + + TRACELVL(5, (mcl_stdout, "-> SendSigPacket: type=%d, buf=x%x, len=%d\n", + type, (int)buf, len)) + ASSERT(type != SIG_CLOSE || buf == NULL); /* no buf with CLOSE */ + if (!initialized) + mcl_sig_initialize(mclcb); + if (!(new_sig = (sig_tab_t *)malloc(sizeof(sig_tab_t)))) { + PRINT_ERR((mcl_stderr, "SendSigPacket: ERROR, no memory")) + mcl_exit(-1); + } + new_sig->next = (sig_tab_t*) NULL; + new_sig->eh_type= type; + new_sig->buf = buf; + new_sig->len = len; + new_sig->target_lvl = 0; /* send on layer 0 */ + new_sig->saddr = NULL; /* by default */ + new_sig->saddr_len = 0; /* by default */ + new_sig->rem2send = max_tx_times[type]; + AddSigToTab(mclcb, new_sig); + if (type == SIG_CLOSE && mclcb->nb_layers > 0) { + tmp_rem2send = new_sig->rem2send; + do { /* tx immediately at least once */ + /* copy var to tmp as mcl_send_pkt could free block */ + mcl_send_pkt(mclcb, 0, NULL, NULL); + tmp_rem2send--; + } while (tmp_rem2send > 0); + CleanupSigTab(mclcb); + } + TRACELVL(5, (mcl_stdout, "<- SendSigPacket:\n")) + return 0; +} + + +/* + * remove and free everything + */ +void +mcl_sig_close (mcl_cb *mclcb) +{ + sig_tab_t *psig, + *prev; + + TRACELVL(5, (mcl_stdout, "-> mcl_sig_close:\n")) + for (psig = mclcb->sig_tab, prev = NULL; psig != NULL; ) { + if (psig->buf) { + free(psig->buf); + psig->buf = NULL; + } + if (psig->saddr && psig->saddr_len > 0) { + free(psig->saddr); + psig->saddr = NULL; + } + if (psig == mclcb->sig_tab) { + mclcb->sig_tab = psig->next; + free(psig); + psig = mclcb->sig_tab; + } else { + ASSERT(prev) + prev->next = psig->next; + free(psig); + psig = prev->next; + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_sig_close:\n")) +} + + +/****** Private Functions *****************************************************/ + + +/* + * initialize everything + * + * WARNING!: keep it coherent with each signaling type (mcl_alc/lct_hdr.h) + */ +static void +mcl_sig_initialize (mcl_cb *mclcb) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_sig_initialize:\n")) + ASSERT(!initialized); + memset(max_tx_times, 0, sizeof(max_tx_times)); + max_tx_times[EXT_NONEWADU] = (short)MAX_TX_EXT_NONEWADU; + max_tx_times[SIG_CLOSE] = (short)MAX_TX_SIG_CLOSE; + initialized = 1; + TRACELVL(5, (mcl_stdout, "<- mcl_sig_initialize:\n")) +} + diff --git a/src/alc/mcl_socket.cpp b/src/alc/mcl_socket.cpp new file mode 100644 index 0000000..5f45749 --- /dev/null +++ b/src/alc/mcl_socket.cpp @@ -0,0 +1,469 @@ +/* $Id: mcl_socket.cpp,v 1.22 2005/05/24 15:43:22 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * Constructor. + */ +mcl_socket::mcl_socket () +{ + this->addrinfo = NULL; + this->reset(); +} + + +/** + * Destructor. + */ +mcl_socket::~mcl_socket () +{ + this->reset(); +} + + +/** + * Reset the class. + * => See header file for more informations. + */ +void +mcl_socket::reset () +{ + + this->id = -1; +#ifdef WIN32 + this->ses_sock = this->priv_sock = INVALID_SOCKET; +#else /* UNIX */ + this->ses_sock = this->priv_sock = 0; +#endif + if (this->addrinfo) { + freeaddrinfo(this->addrinfo); + this->addrinfo = NULL; + } + this->tx_state = SOCK_TX_INVALID; + this->rx_state = SOCK_RX_INVALID; +} + + +/** + * Initialize as a sender. + * => See header file for more informations. + */ +mcl_error_status +mcl_socket::init_as_sender (mcl_cb *const mclcb, + INT32 lay_id, + mcl_addr *ses_addr, + mcl_addr *ifaddr, + char *ifname) +{ + INT32 err; /* error code */ + INT32 mode; /* sender and/or receiver? */ + struct addrinfo hints; + + // split TRACELVL into two part to avoid non-reentrant problems + // of get_addr_string() + TRACELVL(5, (mcl_stdout, + "-> mcl_socket::init_as_sender: lay_id=%d ses_addr=%s/%s", + lay_id, ses_addr->get_addr_string(), + ses_addr->get_port_string())) + TRACELVL(5, (mcl_stdout, " ifaddr=%d ifname=%s\n", + (ifaddr ? ifaddr->get_addr_string() : "null"), + (ifname ? ifname : "null"))) + ASSERT(mclcb->is_a_sender()); + mode = mclcb->ucast_mcast_mode; + this->id = lay_id; + this->addr = *ses_addr; + /* + * This is a sender, in either MODE_UNI_TX or MODE_MCAST_TX. + */ + this->priv_sock = socket(this->addr.get_addr_family(), SOCK_DGRAM, 0); + if (mcl_is_valid_sock(this->priv_sock) == false) { + PRINT_ERR((mcl_stderr, "mcl_socket::init_as_sender: ERROR, socket() failed")) + goto bad; + } + memset(&hints, 0, sizeof(hints)); + hints.ai_family = this->addr.get_addr_family(); + hints.ai_socktype = SOCK_DGRAM; + err = getaddrinfo(this->addr.get_addr_string(), + this->addr.get_port_string(), + &hints, &(this->addrinfo)); + if (err != 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_sender: ERROR, %s\n", + gai_strerror(err))) + goto bad; + } + /* + * multicast specific init + */ + if (mode & MODE_MCAST_TX) { + if (this->addr.is_ipv4_addr()) { +#ifdef WIN32 + /* Windows requires to bind to 0/INADDR_ANY */ + SOCKADDR_IN source_sin; + source_sin.sin_family = AF_INET; + source_sin.sin_port = htons(0); + source_sin.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind(this->priv_sock, + (struct sockaddr FAR *)&source_sin, + sizeof (source_sin)) == SOCKET_ERROR) { + perror("mcl_socket::init_as_sender: ERROR, bind failed"); + goto bad; + } +#else /* UNIX */ + /* do not bind on this socket to get a locally unique + * port number */ +#endif /* OS */ + } else { + /* to bind or not to bind? */ + } + /* specify multicast interface */ + if (//ifname != NULL && + mcast_set_if(this->priv_sock, + this->addr.get_addr_family(), + ifaddr, ifname, + mclcb->get_verbosity()) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_sender: ERROR, mcast_set_if failed for interface name \"%s\"\n", ifname)) + goto bad; + } + /* specify ttl */ + if (mcast_set_ttl(this->priv_sock, + this->addr.get_addr_family(), + mclcb->ttl) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_sender: ERROR, mcast_set_ttl failed for ttl=%d\n", mclcb->ttl)) + goto bad; + } +#ifndef WIN32 + /* turn on the loop back of multicast packets */ + if (mcast_set_loop(this->priv_sock, + this->addr.get_addr_family(), 1) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_sender: ERROR, mcast_set_loop failed\n")) + goto bad; + } +#endif /* NOT WIN32 */ + } + ASSERT(mcl_is_valid_sock(this->priv_sock)); + TRACELVL(4, (mcl_stdout, + "mcl_socket::init_as_sender: layer %d <=> priv_sock=%d: %s/%d\n", + lay_id, (INT32)this->priv_sock, this->addr.get_addr_string(), + this->addr.get_port())) + /* done */ + this->tx_state = SOCK_TX_INITIALIZED; + TRACELVL(5, (mcl_stdout, "<- mcl_socket::init_as_sender:\n")) + return MCL_OK; + +bad: + PRINT_ERR((mcl_stderr, "mcl_socket::init_as_sender: ERROR\n")) + return MCL_ERROR; +} + + +/** + * Initialize as a receiver. + * => See header file for more informations. + */ +mcl_error_status +mcl_socket::init_as_receiver (mcl_cb *mclcb, + INT32 lay_id, + mcl_addr *ses_addr, +#ifdef SSM + mcl_addr *src_addr, +#endif + mcl_addr *ifaddr, + char *ifname) +{ + INT32 err; /* error code */ + INT32 mode; /* sender and/or receiver? */ + struct addrinfo hints; +#ifdef WIN32 + u_long set_non_blocking = 1; /* non blocking read */ + /* NB: must be u_long */ +#endif /* OS_DEP */ + UINT32 reuse_addr; /* for setsockopt */ +#ifdef SOLARIS + INT32 val; /* temporary */ +#endif + + // split TRACELVL into two part to avoid non-reentrant problems + // of get_addr_string() + TRACELVL(5, (mcl_stdout, + "-> mcl_socket::init_as_receiver: lay_id=%d ses_addr=%s/%s", + lay_id, ses_addr->get_port_string(), + ses_addr->get_addr_string())) + TRACELVL(5, (mcl_stdout, " ifaddr=%s ifname=%s\n", + (ifaddr ? ifaddr->get_addr_string() : "null"), + (ifname ? ifname : "null"))) + ASSERT(mclcb->is_a_receiver()); + mode = mclcb->ucast_mcast_mode; + this->id = lay_id; + this->addr = *ses_addr; + /* + * This is a receiver, in either MODE_UNI_RX or MODE_MCAST_RX + * The session socket is always used for mcast rx... + */ + this->ses_sock = socket(this->addr.get_addr_family(), SOCK_DGRAM, 0); + if (mcl_is_valid_sock(this->ses_sock) == false) { + PRINT_ERR((mcl_stderr, "mcl_socket::init_as_receiver: ERROR, socket failed")) + goto bad; + } + /* + * set non-blocking mode for future read on the session sock. + * we noticed that it largely accelerates packet reception + * (see mcl_network.cpp:mcl_recv_pkt()). + * Using the default blocking mode requires to always call + * select() before trying to read packets. In non-blocking + * mode we can read() at any time. + */ +#ifdef WIN32 + if (ioctlsocket(this->ses_sock, FIONBIO, (&set_non_blocking)) == SOCKET_ERROR ) { + perror("mcl_socket::init_as_receiver: ERROR, fcntl failed"); + mcl_exit(1); + } +#else + if (fcntl(this->ses_sock, F_SETFL, O_NONBLOCK) < 0) { + perror("mcl_socket::init_as_receiver: ERROR, fcntl failed"); + mcl_exit(1); + } +#endif +#ifdef SOLARIS + /* + * Increase the default socket size. + * must be large enough to absort packet bursts on each layer! + * Solaris 2.8: + * SunOS sets the maximum buffer size + * for both UDP and TCP to 256 Kbytes. + */ +#define MAX_RX_SOCK_SIZE (256*1024) + val = MCL_RX_SOCK_SIZE; + if (setsockopt(this->ses_sock, SOL_SOCKET, SO_RCVBUF, + (char*)&val, sizeof(val)) < 0) { + perror("mcl_socket::init_as_receiver: ERROR, SO_RCVBUF failed"); + /* non critical error, so ignore */ + } +#else + /* On Linux use the default value. + * System-level values can be changed manually as explained below. + * + * (man -s7 socket): SO_RCVBUF + * Sets or gets the maximum socket receive buffer in bytes. The + * default value is set by the rmem_default sysctl and the maximum + * allowed value is set by the rmem_max sysctl. + * + * So don't set anything, this can be done automatically with an + * appropriate sysctl. + * By default, on a 2.6.9 kernel: + * $ sysctl net.core.rmem_default + * net.core.rmem_default = 110592 + * $ sysctl net.core.rmem_max + * net.core.rmem_max = 131071 + */ +#endif + /* for the future select() */ + FD_SET((u_int)this->ses_sock, &(mclcb->rxlvl.fds)); + mclcb->rxlvl.nfds = max(mclcb->rxlvl.nfds, + (int)this->ses_sock + 1); + mclcb->rxlvl.n_fd++; + + /* allow for reuse of the couple addr/port */ + reuse_addr = 1; + if (mclcb->addr.is_multicast_addr() && + setsockopt(this->ses_sock, SOL_SOCKET, SO_REUSEADDR, + (char *)&reuse_addr, sizeof(reuse_addr)) < 0) { + perror("mcl_socket::init_as_receiver: ERROR, REUSEADDR failed"); + mcl_exit(1); + } + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = this->addr.get_addr_family(); + hints.ai_socktype = SOCK_DGRAM; + hints.ai_flags = AI_PASSIVE; + err = getaddrinfo(this->addr.get_addr_string(), this->addr.get_port_string(), + &hints, &(this->addrinfo)); + if (err != 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_receiver: ERROR, %s\n", + gai_strerror(err))) + goto bad; + } + + /* specify INADDR_ANY */ + if (this->addrinfo->ai_family == AF_INET) { + ((sockaddr_in *) this->addrinfo->ai_addr)->sin_addr.s_addr = + htonl(INADDR_ANY); + } +#ifdef INET6 + else if (this->addrinfo->ai_family == AF_INET6) { + ((sockaddr_in6 *) this->addrinfo->ai_addr)->sin6_addr = + in6addr_any; + } +#endif + + /* now bind the session port number (with INADDR_ANY addr) */ + if (bind(this->ses_sock, this->addrinfo->ai_addr, + this->addrinfo->ai_addrlen) < 0) { + perror("mcl_socket::init_as_receiver: bind"); + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_receiver: ERROR, bind failed\n")) + goto bad; + } + + if (mode & MODE_MCAST_RX) { + /* specify multicast interface */ + if (mcast_set_if(this->ses_sock, + this->addr.get_addr_family(), + ifaddr, ifname, + mclcb->get_verbosity()) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_receiver: ERROR, mcast_set_if failed for ifname %s\n", ifname)) + goto bad; + } +#ifndef WIN32 + /* turn off the loop back of multicast packets */ + /* XXX: is it really required ? */ + if (mcast_set_loop(this->ses_sock, + this->addr.get_addr_family(), 0) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_receiver: ERROR, mcast_set_loop failed\n")) + goto bad; + } +#endif + /* ASM or SSM multicast join */ +#ifdef SSM + if (mclcb->rx.ssm) { + if (mclcb->rx.check_src_addr == false) { + /* in SSM mode but source addr not specified */ + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_receiver: ERROR, SSM mode set but source address not specified\n")) + goto bad; + } + if (ssm_mcast_join (this->ses_sock, + this->addr.get_internal_struct_addr(), + mclcb->rx.src_addr.get_internal_struct_addr(), + ifaddr, ifname, + mclcb->get_verbosity()) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_receiver: ERROR, mcast_join failed\n")) + goto bad; + } + } else +#endif /* SSM */ + { + if (mcast_join (this->ses_sock, + this->addr.get_internal_struct_addr(), + ifaddr, ifname) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::init_as_receiver: ERROR, mcast_join failed\n")) + goto bad; + } + } + } + + ASSERT(mcl_is_valid_sock(this->ses_sock)); + TRACELVL(4, (mcl_stdout, + "mcl_socket::init_as_receiver: layer %d <=> sess_sock=%d: %s/%d\n", + lay_id, (int)this->ses_sock, this->addr.get_addr_string(), + this->addr.get_port())) + /* done */ + this->rx_state = SOCK_RX_INITIALIZED; + TRACELVL(5, (mcl_stdout, "<- mcl_socket::init_as_receiver:\n")) + return MCL_OK; + +bad: + PRINT_ERR((mcl_stderr, "mcl_socket::init_as_receiver: ERROR\n")) + return MCL_ERROR; +} + + +/** + * Close the sockets. + * => See header file for more informations. + */ +mcl_error_status +mcl_socket::close_sockets (mcl_cb *const mclcb) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_close_sockets:\n")) + if (mclcb->ucast_mcast_mode & MODE_MCAST_RX) { + /* leave mcast group first */ +#ifdef SSM + if (mclcb->rx.ssm) { + if (ssm_mcast_leave (this->ses_sock, + this->addr.get_internal_struct_addr(), + mclcb->rx.src_addr.get_internal_struct_addr(), + mclcb->mcast_if_addr, + mclcb->mcast_if_name, + mclcb->get_verbosity()) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::close_sockets: ERROR, ssm_mcast_leave failed\n")) + goto bad; + } + } else +#endif + if (mcast_leave (this->ses_sock, + this->addr.get_internal_struct_addr(), + mclcb->mcast_if_addr, + mclcb->mcast_if_name) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_socket::close_sockets: ERROR, mcast_leave failed\n")) + goto bad; + } + } + if (this->can_rx()) { + /* remove from select() */ + FD_CLR(this->ses_sock, &(mclcb->rxlvl.fds)); + if (mclcb->rxlvl.nfds == (int)this->ses_sock + 1) { + /* TODO: WIN32 compliant? */ + mclcb->rxlvl.nfds--; + } + mclcb->rxlvl.n_fd--; + } + + if (mcl_is_valid_sock(this->priv_sock)) { +#ifdef WIN32 + closesocket(this->priv_sock); + this->priv_sock = INVALID_SOCKET; +#else /* UNIX */ + close(this->priv_sock); + this->priv_sock = 0; +#endif + this->tx_state = SOCK_TX_INVALID; + } + if (mcl_is_valid_sock(this->ses_sock)) { +#ifdef WIN32 + closesocket(this->ses_sock); + this->ses_sock = INVALID_SOCKET; +#else /* UNIX */ + close(this->ses_sock); + this->ses_sock = 0; +#endif + this->rx_state = SOCK_RX_INVALID; + } + TRACELVL(5, (mcl_stdout, "<- mcl_close_sockets:\n")) + return MCL_OK; + +bad: + PRINT_ERR((mcl_stderr, "mcl_socket::close_sockets: ERROR\n")) + return MCL_ERROR; +} + diff --git a/src/alc/mcl_socket.h b/src/alc/mcl_socket.h new file mode 100644 index 0000000..d481649 --- /dev/null +++ b/src/alc/mcl_socket.h @@ -0,0 +1,199 @@ +/* $Id: mcl_socket.h,v 1.5 2005/05/23 11:11:52 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_SOCKET_H /* { */ +#define MCL_SOCKET_H + + +/** + * This class contains the socket(s) on which transmissions or receptions + * are performed. + * Used both for sender and receivers, unicast and multicast. + * In multicast, there is typically one layer class per socket class. + * In unicast, there is typically only one layer class, and one socket class. + */ +class mcl_socket { + +public: + + /****** Public Members ************************************************/ + + /** + * Constructor. + */ + mcl_socket (); + + /** + * Destructor. + */ + ~mcl_socket (); + + /** + * Reset the class. + * Frees all structures (if any) and resets the various fields. + */ + void reset (); + + /** + * Initialize as a sender. + * @param mclcb + * @param lay_id Identifier of the socket class. This is + * an integer in [0; MAX_NB_SOCKETS[. With + * multicast, it is typically the layer id. + * @param ses_addr the session address (mcast/unicast). + * @param ifaddr address of the mcast interface to use or NULL + * @param ifname name of the mcast interface to use or NULL + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status init_as_sender (mcl_cb *const mclcb, + INT32 lay_id, + mcl_addr *ses_addr, + mcl_addr *ifaddr, + char *ifname); + + /** + * Initialize as a receiver. + * + * @param mclcb + * @param lay_id Identifier of the socket class. This is + * an integer in [0; MAX_NB_SOCKETS[. With + * multicast, it is typically the layer id. + * @param ses_addr the session address (mcast/unicast). + * @param src_addr the address of the source, in SSM mode. + * @param ifaddr address of the mcast interface to use or NULL + * @param ifname name of the mcast interface to use or NULL + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status init_as_receiver(mcl_cb *const mclcb, + INT32 lay_id, + mcl_addr *ses_addr, +#ifdef SSM + mcl_addr *src_addr, +#endif + mcl_addr *ifaddr, + char *ifname); + + /** + * Close the sockets. + * Does not free anything (call reset for that). + * @param mclcb + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status close_sockets (mcl_cb *const mclcb); + + /** + * Return the socket class id. + * @return Identifier. + */ + INT32 get_id (); + + /** + * True if transmissions are possible (i.e. if priv_sock has been + * fully initialized). + * @return True if transmissions are possible. + */ + bool can_tx (); + + /** + * True if receptions are possible (i.e. if ses_sock has been + * fully initialized, and with multicast if JOIN has been issued). + * @return True if receptions are possible. + */ + bool can_rx (); + + + /****** Public Attributes *********************************************/ + + /** + * Session socket used for receptions. + * It is bind() to the session address and port number. + */ + MCL_SOCKET ses_sock; + + /** + * Private socket used for transmissions. + * This socket is required to benefit from a private local port + * number. It fully identifies the source of the packets. + */ + MCL_SOCKET priv_sock; + + /** + * Address used on the session socket. + */ + class mcl_addr addr; + + /** + * Address info associated to addr. + * Structure returned by getaddrinfo() syscall. + */ + struct addrinfo *addrinfo; + + +private: + + /****** Private Members ***********************************************/ + + /****** Private Attributes ********************************************/ + + /** + * Identifier of this mcl_socket class. + */ + INT32 id; + + /** + * State of the transmission socket (if any). + */ + enum mcl_socket_tx_state { + SOCK_TX_INVALID, + SOCK_TX_INITIALIZED + }; + mcl_socket_tx_state tx_state; + + /** + * State of the reception socket (if any). + */ + enum mcl_socket_rx_state { + SOCK_RX_INVALID, + SOCK_RX_INITIALIZED, // initialized and joined + SOCK_RX_NOT_JOINED // initialized but no longer joined + // (drop_membership has been issued) + }; + mcl_socket_rx_state rx_state; +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline bool +mcl_socket::can_tx () +{ + return (this->tx_state == SOCK_TX_INITIALIZED); +} + +inline bool +mcl_socket::can_rx () +{ + return (this->rx_state == SOCK_RX_INITIALIZED); +} + +#endif /* } MCL_SOCKET_H */ diff --git a/src/alc/mcl_stats.cpp b/src/alc/mcl_stats.cpp new file mode 100644 index 0000000..bd22043 --- /dev/null +++ b/src/alc/mcl_stats.cpp @@ -0,0 +1,326 @@ +/* $Id: mcl_stats.cpp,v 1.10 2005/01/11 13:12:34 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "mcl_includes.h" + + +/****** Trace functions ******/ + +/* + * Print a sent DU in an understandable way. + */ +void +mcl_print_sent_du (mcl_cb *mclcb, + INT32 type, /* 0 (data) or EH_SIG */ + INT32 val, /* sub-type or layer */ + hdr_infos_t *hdr_infos) +{ + if (type > 0) { + return; + } + if (mclcb->get_verbosity() == 2) { + /* + * produce traces for timely analysis + */ + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tpkt_sent lay=%d aseq=%d bseq=%d dseq=%d %s\n", + time.tv_sec, time.tv_usec, val, + hdr_infos->idf_adu, + hdr_infos->idf_block, hdr_infos->idf_du, + (hdr_infos->is_fec ? "fec" : "data"))) + } else if (mclcb->get_verbosity() >= 3) { + PRINT_OUT((mcl_stdout, + "pkt on lay=%d time=%d aseq=%d/bseq=%d/dseq=%d/%s\n", + val, mcl_time_count, hdr_infos->idf_adu, + hdr_infos->idf_block, hdr_infos->idf_du, + (hdr_infos->is_fec ? "fec" : "data"))) + } +} + + +/* + * Print a received DU in an understandable way. + */ +void +mcl_print_recvd_du (mcl_cb *mclcb, + INT32 type, /* 0 (data) or EH_SIG */ + INT32 val, /* sub-type or layer */ + hdr_infos_t *hdr_infos) +{ + static int prev_level=-1; /* for verbose mode only */ + + ASSERT(EH_SIG > 0); /* to avoid confusion ! */ + /* + if (type == EH_SIG && val == EXT_FTI) { + PRINT_OUT((mcl_stdout, "New ADU (%d: %d bytes, %d blocks)\n", + hdr_infos->idf_adu, hdr_infos->adu_len, + (int)ceil((double)hdr_infos->adu_len / + (double)hdr_infos->block_len))) + } else if (type == EH_SIG && val == EXT_NONEWADU) + */ + if (type == EH_SIG && val == EXT_NONEWADU) { + PRINT_OUT((mcl_stdout, "No New ADU (seq: %d to %d)\n", + mcl_iss, hdr_infos->max_idf_adu)) + } else if (type == EH_SIG && val == SIG_CLOSE) { + PRINT_OUT((mcl_stdout, "\nClose\n")) + } else { + ASSERT(type != EH_SIG); + if (mclcb->get_verbosity() == 1) { + /* + * produce traces for standard compact analysis + */ + if (val == 0) { + PRINT_OUT((mcl_stdout, "\n\t")) + } + if (val != prev_level && val > 0) { + PRINT_OUT((mcl_stdout, "\t\t")) + } + prev_level = val; + if (hdr_infos->is_fec) { + PRINT_OUT((mcl_stdout, "((%d/%d/%d)) ", + hdr_infos->idf_adu, + hdr_infos->idf_block, hdr_infos->idf_du)) + } else { + PRINT_OUT((mcl_stdout, "[%d/%d/%d] ", + hdr_infos->idf_adu, + hdr_infos->idf_block, hdr_infos->idf_du)) + } + } else if (mclcb->get_verbosity() == 2) { + /* + * produce traces for timely analysis + */ + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tpkt_rcvd lay=%d aseq=%d bseq=%d dseq=%d %s\n", + time.tv_sec, time.tv_usec, val, + hdr_infos->idf_adu, + hdr_infos->idf_block, hdr_infos->idf_du, + (hdr_infos->is_fec ? "fec" : "data"))) + } else { + /* + * produce traces for detailed analysis + */ + PRINT_OUT((mcl_stdout, + "pkt on lay=%d time=%d aseq=%d/bseq=%d/dseq=%d/%s\n", + val, mcl_time_count, hdr_infos->idf_adu, + hdr_infos->idf_block, hdr_infos->idf_du, + (hdr_infos->is_fec ? "fec" : "data"))) + } + } +} + + +/****** Statistical functions ******/ + + +/* + * Print sending side statistics + */ +void +mcl_print_tx_stats (mcl_cb *mclcb) +{ + int i; + int max_i = MAX_NB_TX_LAYERS; + stats_t *sp; + struct timeval tv; + + ASSERT(mclcb->get_stats_level()); + sp = &(mclcb->stats); + tv = mcl_get_tvtime(); + PRINT_OUT((stdout, "\n--- TX STATISTICS at t=%ld.%06ld ---\n", + tv.tv_sec, tv.tv_usec)) +#ifdef NEVERDEF + PRINT_OUT((mcl_stdout, "\n--- TX STATISTICS at t=%d ---\n", + mcl_time_count)) +#endif + PRINT_OUT((mcl_stdout, "\tPayload: tx_src_bytes=%ld tx_fec_bytes=%ld\n\ttx bytes per layer:\t", + sp->tx_bytes, sp->tx_fec_bytes)) + for (i=0; i < max_i; i++) { + if (sp->tx_bytes_per_lvl[i] == 0) { + /* no need to consider layers above and including + * this one, they are not used */ + max_i = i; + } else { + PRINT_OUT((mcl_stdout, "%ld\t", + sp->tx_bytes_per_lvl[i])) + } + } + PRINT_OUT((mcl_stdout, "\n\ttx_src_pkts=%ld tx_fec_pkts=%ld\n\ttx pkts per layer:\t", + sp->tx_pkts, sp->tx_fec_pkts)) + for (i=0; i < max_i; i++) { + PRINT_OUT((mcl_stdout, "%ld\t", sp->tx_pkts_per_lvl[i])) + } + PRINT_OUT((mcl_stdout, "\n\tPayload+SIG: tot_snt=%ld tot_rx=%ld bytes\n\tbuf_space=%ld max_buf_space=%ld adu_announced=%ld\n", + sp->tx_totbytes, sp->rx_totbytes, + sp->buf_space, sp->max_buf_space, + sp->adus_announced)) +#ifdef SIMUL_LOSSES + if (sp->tx_simul_loss_sent > 0) { + PRINT_OUT((mcl_stdout, "\tsimul_losses: lost=%ld loss_ratio=%.3f\n", + sp->tx_simul_loss_lost, + (float)sp->tx_simul_loss_lost/(float)sp->tx_simul_loss_sent)) + } +#endif + // mclcb->stats_time_count = STATS_PERIOD / MCL_TIMER_PERIOD; + /* for periodic stats print */ +} + + +/* + * Print receiving side statistics + */ +void +mcl_print_rx_stats (mcl_cb *mclcb) +{ + int i; + int max_i = MAX_NB_TX_LAYERS; + stats_t *sp; + struct timeval tv; + + ASSERT(mclcb->get_stats_level()); + sp = &(mclcb->stats); + tv = mcl_get_tvtime(); + PRINT_OUT((stdout, "\n--- RX STATISTICS at t=%ld.%06ld ---\n", + tv.tv_sec, tv.tv_usec)) +#ifdef NEVERDEF + PRINT_OUT((mcl_stdout, "\n--- RX STATISTICS at t=%d ---\n", + mcl_time_count)) +#endif + PRINT_OUT((mcl_stdout, "\tADUs completed/announced: %ld / %ld\n", + sp->adus_compl, sp->adus_announced)) + /* + * Byte stats + */ + PRINT_OUT((mcl_stdout, "\trx_src_bytes=%ld rx_fec_bytes=%ld including dup_bytes=%ld\n\tbytes per layer:\t", + sp->rx_bytes, sp->rx_fec_bytes, sp->rx_dupl_bytes)) + for (i=0; i < max_i; i++) { + if (sp->rx_bytes_per_lvl[i] == 0) { + /* no need to consider layers above and including + * this one, they are not used */ + max_i = i; + } else { + PRINT_OUT((mcl_stdout, "%ld\t", + sp->rx_bytes_per_lvl[i])) + } + } + /* + * Packet stats + */ +#if defined(RLC) || defined(FLIDS) + PRINT_OUT((mcl_stdout, "\n\trx_src_pkts=%ld rx_fec_pkts=%ld including dup_pkts=%ld lost_pkts=%ld\n\tglobal_ineff_ratio=%.3f\n\tpkts per layer: \t", + sp->rx_pkts, sp->rx_fec_pkts, + sp->rx_dupl_pkts, + sp->rx_lost_pkts, + (float)(sp->rx_pkts + sp->rx_fec_pkts) / (float)(sp->rx_pkts + sp->rx_fec_pkts - sp->rx_dupl_pkts))) +#else + PRINT_OUT((mcl_stdout, "\n\trx_src_pkts=%ld rx_fec_pkts=%ld including dup_pkts=%ld \n\tglobal_ineff_ratio=%.3f\n\tpkts per layer: \t", + sp->rx_pkts, sp->rx_fec_pkts, + sp->rx_dupl_pkts, + (float)(sp->rx_pkts + sp->rx_fec_pkts) / (float)(sp->rx_pkts + sp->rx_fec_pkts - sp->rx_dupl_pkts))) +#endif + for (i=0; i < max_i; i++) { + PRINT_OUT((mcl_stdout, "%ld\t", sp->rx_pkts_per_lvl[i])) + } + PRINT_OUT((mcl_stdout, "\n\tundup pkts per layer:\t")) + for (i=0; i < max_i; i++) { + PRINT_OUT((mcl_stdout, "%ld\t", sp->rx_undup_pkts_per_lvl[i])) + } +#if defined(RLC) || defined(FLIDS) + PRINT_OUT((mcl_stdout, "\n\tlost pkts per layer:\t")) + for (i=0; i < max_i; i++) { + PRINT_OUT((mcl_stdout, "%ld\t", sp->rx_lost_per_lvl[i])) + } +#endif + PRINT_OUT((mcl_stdout, "\n\tData+SIG: tot_snt=%ld tot_rx=%ld bytes\n\tbuf_space=%ld max_buf_space=%ld\n\terrors=%ld bad_demux_label=%ld adu_announced=%ld adu_completed=%ld\n", + sp->tx_totbytes, sp->rx_totbytes, + sp->buf_space, sp->max_buf_space, + sp->errors, sp->bad_demux_label, + sp->adus_announced, sp->adus_compl)) + // mclcb->stats_time_count = STATS_PERIOD / MCL_TIMER_PERIOD; + /* for periodic stats print */ +} + + +/* + * End of reception stats + */ +void +mcl_print_final_stats (mcl_cb *mclcb) +{ + int i; + stats_t *sp; + + ASSERT(mclcb->get_stats_level()); + sp = &(mclcb->stats); + PRINT_OUT((mcl_stdout, "\n--- END OF RX TIMES ---\n")) + + i = sp->finish_index - 1; + if (i < 0) + i = MAX_FIN_TIME - 1; + do { + ASSERT(i >= 0 && i < MAX_FIN_TIME); + if (sp->finish_times[i][STATS_FIN_TIME] == 0 && + sp->finish_times[i][STATS_SEQ] == 0) + return; + PRINT_OUT((mcl_stdout, "\t\tADU seq=%d time=%d\n", + (int)sp->finish_times[i][STATS_SEQ], + (int)sp->finish_times[i][STATS_FIN_TIME])) + i--; + if (i < 0) + i = MAX_FIN_TIME - 1; + } while (i != sp->finish_index); +} + + +#ifdef GET_SYSINFO +/* + * + */ +void +mcl_print_sysinfo (mcl_cb *mclcb) +{ + struct timeval time; + + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tsysinfo ", time.tv_sec, time.tv_usec)) + /* + * edit as required... choose user and appli name... + * ugly but simple! + */ +#if defined(SOLARIS) + system("ps -uroca -o pcpu,pmem,vsz,comm | grep mcl"); + /* + system("top -Uroca -b -d1 | grep mcl &"); + */ +#elif defined(LINUX) + /* broken on linux... */ + /* + * if (mclcb->sender) + * system("top -b -n1 | grep mclsend &"); + * else + * system("top -b -n1 | grep mclrecv &"); + */ +#endif +} +#endif /* GET_SYSINFO */ + diff --git a/src/alc/mcl_stats.h b/src/alc/mcl_stats.h new file mode 100644 index 0000000..a6fbe39 --- /dev/null +++ b/src/alc/mcl_stats.h @@ -0,0 +1,146 @@ +/* $Id: mcl_stats.h,v 1.4 2005/01/11 13:12:34 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_STATS_H /* { */ +#define MCL_STATS_H + +/****** statistics ******/ + + +/* + * statistics collected at the receiver and sender sides + */ +#define MAX_FIN_TIME 512 + +#define STATS_FIN_TIME 0 +#define STATS_SEQ 1 + +typedef struct { + /* + * outgoing traffic stats + */ + UINT32 tx_pkts; /* nb of data packets sent */ + UINT32 tx_sig_pkts; /* sig only packets sent */ + UINT32 tx_bytes; /* nb of data bytes sent*/ + UINT32 tx_totbytes; /* total data+sig bytes sent */ + UINT32 tx_fec_pkts; /* nb of fec data pkts sent */ + UINT32 tx_fec_bytes; /* total nb of fec bytes sent */ + UINT32 tx_pkts_per_lvl[MAX_NB_TX_LAYERS]; /* packets sent on each level */ + UINT32 tx_bytes_per_lvl[MAX_NB_TX_LAYERS]; /* data bytes sent per level */ +#ifdef SIMUL_LOSSES + UINT32 tx_simul_loss_sent; /* total nb of non lost pkts */ + UINT32 tx_simul_loss_lost; /* total nb of simul lost pkts*/ +#endif + /* + * incoming traffic stats + */ + UINT32 rx_pkts; /* total nb of packets recvd */ + /* (doesn't include fec pkts) */ + //UINT32 rx_sig_pkts; /* signaling packets recvd */ + UINT32 rx_bytes; /* nb of data bytes received */ + /* (doesn't include fec pkts) */ + UINT32 rx_totbytes; /* total data+sig bytes recvd */ + UINT32 rx_fec_pkts; /* total nb of fec pkts recvd */ + UINT32 rx_fec_bytes; /* total nb of fec bytes recvd*/ + UINT32 rx_pkts_per_lvl[MAX_NB_TX_LAYERS]; /* packets recvd on each layer */ + /* (includes data+fec packets)*/ + UINT32 rx_bytes_per_lvl[MAX_NB_TX_LAYERS];/* bytes received on each lay */ + /* (includes data+fec packets)*/ + UINT32 rx_undup_pkts_per_lvl[MAX_NB_TX_LAYERS];/* unduplicated pkts recvd*/ + UINT32 rx_dupl_pkts; /* # pkts recvd several times */ + UINT32 rx_dupl_bytes; /* # bytes recvd several times*/ + +#if defined(RLC) || defined(FLIDS) + UINT32 rx_lost_pkts; /* total nb of lost pkts recvd*/ + UINT32 rx_lost_per_lvl[MAX_NB_TX_LAYERS];/* # lost (or delayed!) pkts*/ +#endif + + UINT16 finish_index; /* next available entry in tab*/ + UINT32 finish_times[MAX_FIN_TIME][2]; /* circular buffer of finish */ + /* times [][0] & seq nb [][1] */ + UINT32 adus_compl; /* nb of ADUs completed */ + /* + * errors + */ + UINT32 errors; /* nb of erroneous DUs recvd */ + UINT32 bad_hdr; /* error in header */ + UINT32 bad_demux_label; /* wrong LCT demux label */ + UINT32 other_errors; /* non packet related errors */ + /* + * common stats + */ + UINT32 buf_space; /* current allocated buf space*/ + UINT32 max_buf_space; /* max allocated buffer space */ + UINT32 adus_announced; /* nb of ADUs announced */ +} stats_t; + + +/* + * Public function prototypes. + */ + +/** + * Print transmission statistics. + * @param mclcb + */ +extern void mcl_print_tx_stats (class mcl_cb *mclcb); + +/** + * Print reception statistics (e.g. upon completion of an ADU). + * @param mclcb + */ +extern void mcl_print_rx_stats (class mcl_cb *mclcb); + +/** + * Print final statistics. + * @param mclcb + */ +extern void mcl_print_final_stats (class mcl_cb *mclcb); + +#ifdef GET_SYSINFO +extern void mcl_print_sysinfo (class mcl_cb *mclcb); +#endif + + +/** + * Print a sent DU in an understandable way. + * @param mclcb + * @param type + * @param val + * @param hdr_infos pointer to the header_info structure, that contains + * all the information concerning the sent DU. + */ + +extern void mcl_print_sent_du (class mcl_cb *mclcb, INT32 type, INT32 val, + hdr_infos_t *hdr_infos); + +/** + * Print a received DU in an understandable way. + * @param mclcb + * @param type + * @param val + * @param hdr_infos pointer to the header_info structure, that contains + * all the information concerning a recevied DU. + */ +extern void mcl_print_recvd_du (class mcl_cb *mclcb, INT32 type, + INT32 val, hdr_infos_t *hdr_infos); + +#endif /* } MCL_STATS_H */ diff --git a/src/alc/mcl_tx.cpp b/src/alc/mcl_tx.cpp new file mode 100644 index 0000000..19eaabd --- /dev/null +++ b/src/alc/mcl_tx.cpp @@ -0,0 +1,594 @@ +/* $Id: mcl_tx.cpp,v 1.17 2005/05/18 14:37:56 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +mcl_tx::mcl_tx () +{ + this->next_toi = mcl_iss; + this->reuse_appli_tx_buffer = false; + this->adu_head = NULL; + this->keep_data_mode_set = false; + this->adu_start = NULL; + this->adu_end = NULL; + this->first_tx_for_mclcb = true; + this->next_adu_is_of_high_prio = false; + this->there_is_more_to_tx = false; +} + + +mcl_tx::~mcl_tx () +{ + ASSERT(this->adu_head == NULL); +} + + +/** + * Set the "keep data" mode. + * => See header file for more informations. + */ +mcl_error_status +mcl_tx::keep_data (mcl_cb *const mclcb) +{ + if (this->keep_data_mode_set == true) { + PRINT_ERR((mcl_stderr, + "mcl_tx::keep_data: ERROR, keep data mode already set\n")) + return MCL_ERROR; + } + ASSERT(this->adu_start == NULL && this->adu_end == NULL); + this->keep_data_mode_set = true; + TRACELVL(5, (mcl_stdout, " mcl_tx::keep_data: set\n")) + return MCL_OK; +} + + +/** + * End the "keep data" mode, or said differently, push all accumulated + * data. + * => See header file for more informations. + */ +mcl_error_status +mcl_tx::push_data (mcl_cb *const mclcb) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_tx::push_data: start %d, end %d\n", + this->adu_start->seq, this->adu_end->seq)) + if (this->keep_data_mode_set == false) { + PRINT_ERR((mcl_stderr, + "mcl_tx::push_data: ERROR, keep data mode not set\n")) + return MCL_ERROR; + } + if (this->adu_start == NULL || this->adu_end == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_tx::push_data: ERROR, no ADU submitted\n")) + return MCL_ERROR; + } + /* and now do the tx plannification... */ + UpdateTxPlanning(mclcb, this->adu_start, this->adu_end); + this->keep_data_mode_set = 0; + this->adu_start = this->adu_end = NULL; +#if 0 + mclcb->lastADUseq = LastADUSeq(mclcb, mclcb->txlay_tab[0].adu_head); + for (INT32 i = 0; i < MAX_NB_TX_LAYERS; i++) { + mclcb->txlay_tab[i].adu_head = NULL; + } +#endif + TRACELVL(5, (mcl_stdout, "<- mcl_tx::push_data:\n")) + return MCL_OK; +} + + +/** + * Register a new ADU when in "keep data" mode. + * => See header file for more informations. + */ +void +mcl_tx::register_adu_in_keep_data_mode (mcl_cb *const mclcb, + adu_t *adu) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_tx::push_data: adu %d\n", adu->seq)) + ASSERT(this->keep_data_mode_set); + if (this->adu_start == NULL) + this->adu_start = adu; + if (this->adu_end == NULL || adu->seq > this->adu_end->seq) + this->adu_end = adu; + if (adu->seq < this->adu_start->seq) { + /* required for instance with the FDT of FLUTE if + * this latter is submitted after other ADUs */ + this->adu_start = adu; + } +} + + +/** + * Free all the adus of the tx adu list. + * => See header file for more informations. + */ +void +mcl_tx::free_all_adu (mcl_cb *const mclcb) +{ + adu_t *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx::free_all_adu:\n")) + while ((adu = adu_head) != NULL) { + this->remove_adu(mclcb, adu); + /* now free the adu and all of its blocks/dus */ + mcl_tx_free_this_adu(mclcb, adu); + free(adu); + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx::free_all_adu:\n")) +} + + +/** + * Copy data from the buffers/files specified by the msghdr to the ADU. + * => See header file for more informations. + */ +mcl_error_status +mcl_tx::copy_from_iovec_to_adu + (mcl_cb *const mclcb, + struct mcl_msghdr *msg, + adu_t *adu) +{ + UINT32 len; /* size without padding */ + UINT32 padded_len; /* size with padding to 0 for FEC */ + struct mcl_iovec *iov; /* iovec */ + bool is_buffer; /* does input come in a buffer or not */ + void *data; /* input data buffer (if applicable) */ + INT32 fd; /* input data file (if applicable) */ + + TRACELVL(5, (mcl_stdout, + "-> mcl_tx::copy_from_iovec_to_adu:\n")) + + if (msg->msg_iovlen != 1) { + /* + * Complex case where there are multiple iovec entries. + */ + PRINT_ERR((mcl_stderr, + "mcl_tx::copy_from_iovec_to_adu: ERROR, having more than 1 iovec entry is not supported!\n")) + goto error; + //return this->copy_from_multiple_iovec_entries(mclcb, msg,adu); + } + /* + * easy case where there is one iovec entry. + */ + /* + * find the input data file/buffer. + */ + iov = msg->msg_iov; + if (iov->iov_type == MCL_IOV_TYPE_BUFFER) { + is_buffer = true; + data = iov->iov_base; + } else { + is_buffer = false; + if (iov->iov_filename == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_tx::copy_from_iovec_to_adu: ERROR, NULL iov_filename\n")) + goto error; + } + fd = mcl_file_open(iov->iov_filename, O_RDONLY, 0); + if (fd < 0) { + PRINT_ERR((mcl_stderr, + "mcl_tx::copy_from_iovec_to_adu: ERROR, mcl_file_open() failed for iov_filename \"%s\"\n", + iov->iov_filename)) + return MCL_ERROR; + } + if (mcl_file_lseek(fd, iov->iov_offset) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_tx::copy_from_iovec_to_adu: ERROR, mcl_file_lseek() failed\n")) + return MCL_ERROR; + } + } + /* + * calculate the ADU length. + */ + len = iov->iov_len; + adu->len = len; + padded_len = (UINT32)(ceil((double)len / (double)adu->symbol_len) + * (double)adu->symbol_len); + adu->padded_len = padded_len; +#ifdef VIRTUAL_TX_MEM + if (mcl_vtm_can_store_in_vtm(mclcb, padded_len)) { + /* + * use the VTMEM service to register data + */ + if (mcl_vtm_store_data(mclcb, adu, NULL, (char*)data, fd, + len, padded_len) ) { + PRINT_ERR((mcl_stderr, + "mcl_tx::copy_from_iovec_to_adu: Virtual Tx Memory service failed\n")) + goto error; + } + if (is_buffer && mclcb->tx.can_reuse_appli_buf()) { + /* + * free the data buffer. + * In fact using reuse_appli is here useless! + */ + free((void*)data); + PRINT_ERR((mcl_stderr, "mcl_tx::copy_from_iovec_to_adu: using reuse_appli_tx_buffer is useless in Virtual Tx Memory mode\n")) + goto error; /* NB: error can be ignored safely though */ + } + TRACELVL(5, (mcl_stdout, + "<- mcl_tx::copy_from_iovec_to_adu:\n")) + return MCL_OK; + } +#endif /* VIRTUAL_TX_MEM */ + /* + * store in physical tx memory (ptm) + */ + if (is_buffer) { + /* + * input data is already in a buffer. + */ + if (mclcb->tx.can_reuse_appli_buf()) { + /* take control of buf and avoid an extra data copy */ + if (padded_len != len) { + /* add a null padding to end of block */ + if (!(adu->data = (char*)realloc((void*)data, padded_len))) { + PRINT_ERR((mcl_stderr, + "mcl_tx::copy_from_iovec_to_adu: out of memory\n")) + goto error; + } + memset(adu->data + len, 0, padded_len - len); + } + } else { + if (!(adu->data = (char*)malloc(padded_len))) { + PRINT_ERR((mcl_stderr, + "mcl_tx::copy_from_iovec_to_adu: out of memory\n")) + goto error; + } + memcpy(adu->data, data, len); + memset(adu->data + len, 0, padded_len - len);/*padding*/ + /*PRINT_OUT((mcl_stdout, + "copied data to x%x, len=%d, padded_len=%d\n", + (int)adu->data, len, padded_len))*/ + } + } else { + /* no need to care about can_reuse_appli_buf() here */ + if (!(adu->data = (char*)malloc(padded_len))) { + PRINT_ERR((mcl_stderr, + "mcl_tx::copy_from_iovec_to_adu: out of memory\n")) + goto error; + } + if (mcl_file_read(fd, adu->data, len) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_tx::copy_from_iovec_to_adu: ERROR, mcl_file_read() failed\n")) + goto error; + } + memset(adu->data + len, 0, padded_len - len);/*padding*/ + /*PRINT_OUT((mcl_stdout, + "copied data to x%x, len=%d, padded_len=%d\n", + (int)adu->data, len, padded_len))*/ + } +#ifdef VIRTUAL_TX_MEM + if (mclcb->vtm_used) { + /* remember it is kept in physical memory */ + mcl_vtm_register_in_ptm(mclcb, adu, NULL, padded_len); + } +#endif /* VIRTUAL_TX_MEM */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx::copy_from_iovec_to_adu:\n")) + return MCL_OK; + +error: + TRACELVL(5, (mcl_stdout, + "<- mcl_tx::copy_from_iovec_to_adu: ERROR\n")) + return MCL_ERROR; +} + + +/* + * for packet traces + * store msg in a buf and print everything atomically + */ +#define TRC_BUF_SIZE 1024 +static char trc_buf[TRC_BUF_SIZE]; +static UINT32 trc_offset = 0; +#define ADD_TO_STR_BUF(m) { if (trc_offset + strlen(m) < TRC_BUF_SIZE) { \ + strcpy(&trc_buf[trc_offset], m); \ + trc_offset += strlen(m); \ + } } + + +/** + * Try to send as much data as possible in a tx tick for this session. + * => See header file for more informations. + */ +void +mcl_tx::try_to_send (mcl_cb *mclcb) +{ + INT32 i; + INT32 du_nb = 0; /* number of DUs to send */ + INT32 du_nb_high = 0; /* number of DUs to send */ + txlay_t *tl; + //bool something_sent; /* has any DU been sent on base layer?*/ + double true_du_per_tick; /* takes into account fractions */ + /* of DUs not sent in previous tick */ + INT32 du_for_this_tick; /* actual rounded # DUs to send */ + + TRACELVL(5, (mcl_stdout, "-> mcl_tx::try_to_send: mclcb=x%x\n", (int)mclcb)) + /* + * see what to send next for each tx layer. + */ + if (mclcb->is_a_sender() && !mclcb->fsm.is_closed(mclcb)) { + //something_sent= false; /* reset first */ + this->there_is_more_to_tx = false; /* reset first */ + for (i = 0, tl = mclcb->txlay_tab; i < mclcb->nb_layers; + i++, tl++) { + if (tl->tx_high_timer > 0) { + tl->tx_high_timer--; + } else { + /* number of ticks per second (in order to + * send important data every second) */ + tl->tx_high_timer = (INT32) + IMPORTANT_DATA_FREQUENCY / MCL_TIMER_PERIOD; + } + /* + * how many DUs (of high or normal priority) should + * be sent? + */ + true_du_per_tick = tl->du_per_tick + tl->remaining_du_per_tick; + du_for_this_tick = (INT32)true_du_per_tick; + tl->remaining_du_per_tick = true_du_per_tick - du_for_this_tick; + if (tl->tx_high_timer == 0 || tl->tx_high_flush == true) { + du_nb_high = min(du_for_this_tick, + tl->tx_tab_high->tot_rem); + } else { + du_nb_high = 0; + } + du_nb = min(du_for_this_tick - du_nb_high, + tl->tx_tab->tot_rem); + if (du_nb_high + du_nb > 0) { + /* + * something to send! + */ + if (this->first_tx_for_mclcb) { + this->first_tx_for_mclcb = false; +#ifdef RLC + if (mclcb->congestion_control == RLC_CC) { + /* reset SP at first pkt tx */ + rlc_reset_tx_sp(mclcb); + } +#endif + } + this->send_pkt(mclcb, tl, du_nb, du_nb_high); +#if 0 + if (i == 0) { + /* something sent on base layer */ + something_sent = true; + } +#endif + } + if (tl->tx_tab->tot_rem == 0) { + /* + * get ready for a new tx cycle + * on that layer for tx_tab, if needed. + */ + tl->tx_tab->new_tx_cycle(mclcb); + } + + if (tl->tx_tab_high->tot_rem == 0) { + /* + * get ready for a new tx cycle + * on that layer for tx_tab_high, if needed. + */ + if (tl->tx_high_flush == true) + { + /* we finished flushing */ + tl->tx_high_flush = false; + } + tl->tx_tab_high->new_tx_cycle(mclcb); + } + } + /* + * print all the packet traces atomically + */ + if (trc_offset > 0) { + ADD_TO_STR_BUF("\n"); + PRINT_OUT((mcl_stdout, trc_buf)) + trc_offset = 0; + } + tl = mclcb->txlay_tab; + if ((tl->tx_tab_high->tot_rem > 0) || (tl->tx_tab->tot_rem > 0)) { + /* there remain DUs to transmit next time for base + * layer... */ + this->there_is_more_to_tx = true; + } else if (mclcb->fsm.no_new_adu(mclcb)) { + /* + * no transmission on base layer! + * stop everything and send a close message... + */ + mclcb->fsm.update_tx_state(mclcb, TEVENT_ALL_DU_SENT); + SendCLOSE(mclcb); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_SENT); + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx::try_to_send:\n")) +} + + +/** + * Send this number of DUs for this session on this layer. + * => See header file for more informations. + */ +void +mcl_tx::send_pkt (mcl_cb *mclcb, + txlay_t *tl, + INT32 du_nb, + INT32 du_nb_high) +{ + du_t *du = NULL; + int rem; + char s[64]; /* for string */ + + TRACELVL(5, (mcl_stdout, + "-> mcl_tx::sendit: lay %d: %d DUs, %d high prio DUs\n", + tl->layer, du_nb, du_nb_high)) + ASSERT(du_nb > 0 || du_nb_high > 0); + ASSERT(tl && (tl->tx_tab->tot_rem >= du_nb)); + ASSERT((tl->tx_tab_high->tot_rem >= du_nb_high)); + + if (mclcb->get_verbosity() == 1) + ADD_TO_STR_BUF("\t\t") + + /* high importance data */ + for (rem = du_nb_high; rem > 0; rem--) { + du = tl->tx_tab_high->get_next_du (mclcb); + ASSERT(du); + if (mclcb->get_verbosity() == 1) { + /* compact, imprecise but easily readable trace */ +#ifdef FEC + if (du->is_fec) + sprintf(s, "(%d/%d/%d) ", du->block->adu->seq, + du->block->seq, du->seq); + else +#endif /* FEC */ + sprintf(s, "[%d/%d/%d] ", du->block->adu->seq, + du->block->seq, du->seq); + ADD_TO_STR_BUF(s) + } + /* then send data*/ + mcl_send_pkt(mclcb, tl->layer, du, du->block->adu); + } + + /* normal importance data */ + for (rem = du_nb; rem > 0; rem--) { + du = tl->tx_tab->get_next_du (mclcb); + ASSERT(du); + if (mclcb->get_verbosity() == 1) { + /* compact, imprecise but easily readable trace */ +#ifdef FEC + if (du->is_fec) + sprintf(s, "(%d/%d/%d) ", du->block->adu->seq, + du->block->seq, du->seq); + else +#endif /* FEC */ + sprintf(s, "[%d/%d/%d] ", du->block->adu->seq, + du->block->seq, du->seq); + ADD_TO_STR_BUF(s) + } + /* then send data*/ + mcl_send_pkt(mclcb, tl->layer, du, du->block->adu); + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx::sendit:\n")) +} + + +/* + * Find an ADU in the tx list with its sequence number and instance id. + * If parameter FDT_instanceid is -1, don't care for instance ID when + * searching ADU, and take the first ADU with the specified sequence + * number seq. + */ +adu_t * +mcl_tx::find_adu (mcl_cb *const mclcb, + UINT32 idf_adu, + INT32 FDT_instanceid) +{ + adu_t *adu; + adu_t *list = this->adu_head; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx::find_adu: seq=%d\n", idf_adu)) + if (!list) { + TRACELVL(5, (mcl_stdout, "<- mcl_tx::find_adu: empty list\n")) + return NULL; + } + /* start from the highest seq number */ + adu = list->prev; + while (1) { + ASSERT(adu); + if (adu->seq == idf_adu && ((INT32) adu->FDT_instanceid == FDT_instanceid || FDT_instanceid == -1)) { + /* found */ + TRACELVL(5, (mcl_stdout, "<- mcl_tx::find_adu: found\n")) + return adu; + } + if (adu == list || adu->seq < idf_adu) { + /* we have cycled or new adu cannot be in list */ + TRACELVL(5, (mcl_stdout, "<- mcl_tx::find_adu: new\n")) + return NULL; + } + adu = adu->prev; + } +} + + +#if 0 +/* + * scan all the remaining du transmissions and free + * buffers for ADUs completely sent + */ +void +mcl_tx_cleanup (mcl_cb *mclcb) +{ + adu_t *list; /* head of adu list */ + adu_t *adu; + txlay_t *tl; + int i; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_cleanup:\n")) + ASSERT(mclcb->delivery_mode == DEL_MODE_PUSH); + if ((list = mclcb->txlay_tab[0].adu_head) != NULL) { + /* + * reset the in_txtab flag for each ADU + */ + adu = list; + do { +#ifdef DEBUG + if (adu->blocking_struct.block_nb == 0) { + /* already free'ed, just to check */ + ASSERT((adu->block_head == NULL && + adu->data == NULL)) + } +#endif /* DEBUG */ + adu->in_txtab = 0; /* by default not in txtab */ + adu = adu->next; + } while (adu != list); + /* + * search in txtab all the layers which ADUs have pending DUs + */ + for (i = 0, tl = mclcb->txlay_tab; i < mclcb->nb_layers; + i++, tl++) { + tl->tx_tab->mark_adus_in_txtab(mclcb); + tl->tx_tab_high->mark_adus_in_txtab(mclcb); + } + /* + * and free ADUs with no pending DU + */ + adu = list; + do { + if (adu->blocking_struct.block_nb > 0 && adu->in_txtab == 0) { + /* + * everything has been sent; free this ADU + * nb: in fact adu buffer is not free'ed! + */ + mcl_tx_free_this_adu(mclcb, adu); + ASSERT((adu->blocking_struct.block_nb == 0 && + adu->block_head == NULL && + adu->data == NULL)) + } + adu = adu->next; + } while (adu != list); + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx_cleanup: ok\n")) +} +#endif + + + diff --git a/src/alc/mcl_tx.h b/src/alc/mcl_tx.h new file mode 100644 index 0000000..60d2364 --- /dev/null +++ b/src/alc/mcl_tx.h @@ -0,0 +1,437 @@ +/* $Id: mcl_tx.h,v 1.2 2005/02/25 14:13:11 moi Exp $ */ +/* + * Copyright (c) 2005 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_TX_H +#define MCL_TX_H + + +/** + * This Class controls many aspects related to transmissions. + */ +class mcl_tx { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + mcl_tx (); + + /** + * Default destructor. + */ + ~mcl_tx (); + + /** + * Set the TOI (AKA ADU sequence number) to use for the next + * submitted adu. + * @param toi toi to use for the next submitted adu. + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_next_toi (UINT32 toi); + + /** + * Return the TOI (AKA ADU sequence number) to use for a newly + * submitted adu. + * @return returns the adu sequence number to use + */ + UINT32 get_next_toi (); + + /** + * Increment the TOI (AKA ADU sequence number) to use for a + * newly submitted adu. + */ + void incr_next_toi (); + + /** + * Set the "keep data" mode. + * The keep_data mode, when set, postpones the scheduling of ADUs. + * Usefull to increase transmission efficiency when dealing + * with a large number of objects. + * @param mclcb + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status keep_data (mcl_cb *const mclcb); + + /** + * End the "keep data" mode, or said differently, push all accumulated + * data. + * @param mclcb + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status push_data (mcl_cb *const mclcb); + + /** + * Are we in "keep data" mode? + * @param mclcb + * @return returns true if the "keep data" mode is set. + */ + bool is_in_keep_data_mode (); + + /** + * Register a new ADU when in "keep data" mode. + * Here scheduling will be done later when the application + * issues a PUSH, so remember this ADU in the meantime. + * @param mclcb + * @param adu ADU to register. + */ + void register_adu_in_keep_data_mode (mcl_cb *const mclcb, + adu_t *adu); + +#if 0 + /** + * Return the highest adu seq number ever submitted by the sending app. + * @return highest adu seq number submitted + */ + UINT32 get_highest_submitted_adu_seq () const; +#endif + + /** + * Informs there won't be any more ADU. + * This function is called as soon as the sending application + * issues a mcl_close(). + * @param mclcb + */ + void set_no_new_adu (mcl_cb *const mclcb); + + /** + * Insert the adu in the tx adu list. + * This ADU list is ordered in increasing TOI number. + * @param mclcb + * @param adu + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status insert_adu (mcl_cb *const mclcb, + adu_t *const adu); + /** + * Remove the adu from the tx adu list. + * @param mclcb + * @param adu + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status remove_adu (mcl_cb *const mclcb, + adu_t *const adu); + + /** + * Get the first adu of the tx adu list. + * @param mclcb + */ + adu_t *get_first_adu (mcl_cb *const mclcb); + + /** + * Get the last adu of the tx adu list. + * @param mclcb + * @return last adu of the list. + */ + adu_t *get_last_adu (mcl_cb *const mclcb); + + /** + * Get the highest TOI of the tx adu list. + * This is also the last ADU's TOI since the list is ordered. + * @param mclcb + * @return TOI of the last adu of the list. + */ + UINT32 get_highest_toi (mcl_cb *const mclcb); + + /** + * Free all the adus of the tx adu list. + * This function is only called at session close/abort. + * @param mclcb + */ + void free_all_adu (mcl_cb *const mclcb); + + + /** + * Find an ADU in the tx list with its sequence number and instance id. + * If parameter FDT_instanceid is -1, don't care for instance ID when + * searching ADU, and take the first ADU with the specified sequence + * number seq. + * @param mclcb + * @param idf_adu ADU seq number + * @param FDT_instanceid FDT instance id + * @return returns a pointer to the adu if found, NULL otherwise + */ + adu_t *find_adu (mcl_cb *const mclcb, + UINT32 idf_adu, + INT32 FDT_instanceid); + + /** + * Determine if application buffer can be reused by MCL or not. + * @param val boolean + */ + void set_reuse_appli_buf_bool (bool val); + + /** + * True if application buffer can be reused by MCL. + * @return boolean + */ + bool can_reuse_appli_buf () const; + + /** + * Copy data from the buffers/files specified by the msghdr to the ADU. + * Depending on the storage mode, data may be copied to an internal + * buffer, or on the contrary kept on disk. + * @param mclcb + * @param msg Message control struct used by mcl_sndmsg/mcl_recvmsg. + * @param flags Flags used by mcl_sndmsg/mcl_recvmsg. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status copy_from_iovec_to_adu + (mcl_cb *const mclcb, + struct mcl_msghdr *msg, + adu_t *adu); + +#if 0 + /** + * Get the transmission rate in bits per second (bps). + * @return current transmission rate + */ + float get_bps_tx_rate () const; + + /** + * Get the transmission rate in packets per second (pps). + * @return current transmission rate + */ + float get_pkt_per_sec_tx_rate () const; + + /** + * Get the transmission rate in packets per tick (ppt). + * @return current transmission rate + */ + float get_pkt_per_tick_tx_rate () const; + + /** + * Set the transmission rate in bits per second (bps). + * The desired rate can be adjusted so that the is an integral + * number of packets per tick. + * @param mclcb + * @param desired_rate desired rate in bits per second + * @return rate actually set + */ + float set_bps_tx_rate (mcl_cb *const mclcb, + const float desired_rate); +#endif + +#if 0 // not yet + /** + * Set a pre-defined transmission profile. + * @param mclcb + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_tx_profile (mcl_cb *const mclcb, + mcl_tx_profile prof); +#endif + + /** + * Try to send as much data as possible in a tx tick for this session. + * This is the general sending function. + * @param mclcb + */ + void try_to_send (mcl_cb *mclcb); + + + /****** Public Attributes *********************************************/ + + /** + * True if one or more DUs remain to be send. + * Used by the mcl_wait_event() function. + */ + bool there_is_more_to_tx; + + /** + * True if next ADU is of high priority (e.g. control data, + * FDT with FLUTE). + */ + bool next_adu_is_of_high_prio; + + +private: + /****** Private Members ***********************************************/ + /** + * Send this number of DUs for this session on this layer. + * @param mclcb + * @param du_nb Number of DUs to send + */ + void send_pkt (mcl_cb *const mclcb, + struct txlay *tl, + INT32 du_nb, + INT32 du_nb_high); + + /****** Private Attributes ********************************************/ + /** TOI (AKA ADU sequence number) to use for the next submitted ADU. */ + UINT32 next_toi; + + /** True to take control of buffer */ + bool reuse_appli_tx_buffer; + + /** head of ADU doubly linkded list. */ + adu_t *adu_head; + + /** the keep_data mode, when set, postpones the scheduling of ADUs. */ + bool keep_data_mode_set; + /** First ADU concerned by the keep_data mode. */ + adu_t *adu_start; + /** Last ADU concerned by the keep_data mode. */ + adu_t *adu_end; + + /* initially true, false once a packet has been sent for this session */ + bool first_tx_for_mclcb; +#if 0 + /** Transmission rate in bits per second (bps) */ + float bps_tx_rate; + /** Transmission rate in packets per second (pps) */ + float pps_tx_rate; + /** Transmission rate in packets per tick of the periodic timer (ppt). + * It must be an integer */ + float ppt_tx_rate; +#endif + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline mcl_error_status +mcl_tx::set_next_toi (UINT32 toi) +{ + this->next_toi = toi; + return MCL_OK; +} + +inline UINT32 +mcl_tx::get_next_toi () +{ + return this->next_toi; +} + +inline void +mcl_tx::incr_next_toi () +{ + this->next_toi++; +} + +inline bool +mcl_tx::is_in_keep_data_mode () +{ + return this->keep_data_mode_set; +} + +#if 0 +inline UINT32 +mcl_tx::get_highest_submitted_adu_seq () const +{ + return this->highest_adu_seq; +} +#endif + +inline void +mcl_tx::set_no_new_adu (mcl_cb *const mclcb) +{ + //if (mclcb->fsm.no_new_adu(mclcb) == false) + // exit(-1); + //ASSERT(mclcb->fsm.no_new_adu(mclcb)); +} + +inline mcl_error_status +mcl_tx::insert_adu (mcl_cb *const mclcb, + adu_t *const adu) +{ + //ASSERT(mclcb->fsm.no_new_adu(mclcb) == false); + //return adu->insert_in_list(mclcb, &(this->adu_head)); + mcl_insert_adu(mclcb, adu, &(this->adu_head)); + return MCL_OK; +} + +inline mcl_error_status +mcl_tx::remove_adu (mcl_cb *const mclcb, + adu_t *const adu) +{ + //adu->remove_from_list(mclcb, &(this->adu_head)); + mcl_remove_adu(mclcb, adu, &(this->adu_head)); + return MCL_OK; +} + + +inline adu_t * +mcl_tx::get_first_adu (mcl_cb *const mclcb) +{ + return this->adu_head; +} + +inline adu_t * +mcl_tx::get_last_adu (mcl_cb *const mclcb) +{ + //return ((this->adu_head != NULL) ? this->adu_head->get_prev() : NULL); + return ((this->adu_head != NULL) ? this->adu_head->prev : NULL); +} + +inline UINT32 +mcl_tx::get_highest_toi (mcl_cb *const mclcb) +{ + ASSERT(this->adu_head); + return (mcl_get_highest_toi(mclcb, this->adu_head)); +} + +#if 0 +inline adu_t * +mcl_tx::find_adu (mcl_cb *const mclcb, + UINT32 idf_adu) +{ + return this->adu_head->find_in_list(mclcb, this->adu_head, idf_adu); +} +#endif + +inline void +mcl_tx::set_reuse_appli_buf_bool (bool val) +{ + this->reuse_appli_tx_buffer = val; +} + +inline bool +mcl_tx::can_reuse_appli_buf () const +{ + return this->reuse_appli_tx_buffer; +} + +#if 0 +inline float +mcl_tx::get_bps_tx_rate () const +{ + return this->bps_tx_rate; +} + +inline float +mcl_tx::get_pkt_per_sec_tx_rate () const +{ + return this->pps_tx_rate; +} + +inline float +mcl_tx::get_pkt_per_tick_tx_rate () const +{ + return this->ppt_tx_rate; +} +#endif + +#endif // !MCL_TX_H + diff --git a/src/alc/mcl_tx_prof.cpp b/src/alc/mcl_tx_prof.cpp new file mode 100644 index 0000000..36d0614 --- /dev/null +++ b/src/alc/mcl_tx_prof.cpp @@ -0,0 +1,238 @@ +/* $Id: mcl_tx_prof.cpp,v 1.18 2005/05/18 14:37:56 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "mcl_includes.h" + + +/* Local private function prototypes */ +static void mcl_print_tx_rates (mcl_cb *mclcb); + + +/* + * if compiled with IPv6 support, then be conservative: reserve room + * for IPv6 headers... + */ +#ifdef INET6 +#define UDP_IP_HDR_SZ UDP_IPv6_HEADER_SIZE +#else +#define UDP_IP_HDR_SZ UDP_IPv4_HEADER_SIZE +#endif + + + +/** transmission profile parameters structure. */ +typedef struct { + INT32 layer_nb; /* max number of layers */ + INT32 datagram_sz; /* datagram size; the higher, the better */ + double tx_rate; /* in packets per tick on the base layer */ + INT32 rlc_aggressive_cc;/* aggressive congestion ctrl setup for LAN tx*/ +} tx_prof_t; + +/* + * WARNING1: keep synchronized with mcl_lib.h + * WARNING2: changing datagram_size must be done both at source AND receivers + * by using the appropriate tx profile argument. + */ +static tx_prof_t tx_prof_tab[] = { + /* lay datagram_size tx_rate aggr_cc*/ +/* LOW_RATE_INTERNET */{10, 576 - UDP_IP_HDR_SZ, 3.0, 0}, +/* MID_RATE_INTERNET */{10, 576 - UDP_IP_HDR_SZ, 20.0, 0}, +/* HIGH_SPEED_INTERNET */{10, 1024 - UDP_IP_HDR_SZ, 40.0, 0}, + +/* HIGH_SPEED_LAN */ {1, 1400 - UDP_IP_HDR_SZ, 800.0, 0}, +}; + +/* + * Additional rules: + * + * *_INTERNET: + * CC: can be either RLC or FLID-SL. If none, try FLID-SL, otherwise + * RLC, otherwise error + * Single layer mode: set to false since it is incompatible with CC + * + * HIGH_SPEED_LAN: + * CC: set to NO_CC. If another one is choosen, change it to NO_CC. + * Single layer mode: set to true + */ + + +/* + * set a pre-defined profile, modifying some MCL parameters as required + */ +INT32 +mcl_set_tx_profile (mcl_cb *mclcb, + int profile) +{ + INT32 val; + double dval; // same as val but with double format + INT32 err; + + TRACELVL(5, (mcl_stdout, "-> mcl_set_tx_profile: prof=%d\n", profile)) + switch (profile) { + case MCL_TX_PROFILE_LOW_RATE_INTERNET: + case MCL_TX_PROFILE_MID_RATE_INTERNET: + case MCL_TX_PROFILE_HIGH_SPEED_INTERNET: + /* NB: call mcl_ctl2 internal func as we are already locked! */ + mclcb->single_layer_mode = false; + /* maximum number of layers */ + val = tx_prof_tab[profile].layer_nb; + err = mcl_ctl2(mclcb, MCL_OPT_LAYER_NB, (void*)&val, + sizeof(val)); + if (err) goto error; + /* datagram size */ + val = tx_prof_tab[profile].datagram_sz; + err = mcl_ctl2(mclcb, MCL_OPT_DATAGRAM_SIZE, (void*)&val, + sizeof(val)); + if (err) goto error; + /* transmission rate */ + dval = tx_prof_tab[profile].tx_rate; + err = mcl_ctl2(mclcb, MCL_OPT_TX_RATE, (void*)&dval, + sizeof(dval)); + if (err) goto error; + /* + * if a congestion control of type RLC or FLID-SL is already + * specified, that's ok. Otherwise choose one, by default + * FLID-SL, if not available RLC, otherwise return an error. + */ + if (mclcb->congestion_control != RLC_CC && + mclcb->congestion_control != FLID_SL_CC) { +#ifdef FLIDS + val = FLID_SL_CC; /* default */ +#elif defined(RLC) + val = RLC_CC; +#else + ERROR, specifying a non null congestion control + protocol is mandatory for an Internet profile. + Add RLC or FLID-SL support in mcl_profile.h and + recompile MCL... +#endif + err = mcl_ctl2(mclcb, MCL_OPT_SET_CC_SCHEME, + (void*)&val, sizeof(val)); + if (err) goto error; + } + break; + + case MCL_TX_PROFILE_HIGH_SPEED_LAN: + /* + * LAN case (no multicast routing), so switch to single + * layer mode and remove congestion control. + */ + mclcb->single_layer_mode = true; + mclcb->nb_layers = 1; /* 1 layer only! */ + mclcb->max_nb_layers = 1; /* 1 layer only! */ + mclcb->scheduler = MCL_SCHED_LCT1; /* mix everything */ + /* + * Required for FLUTE interoperability tests, but a + * limitation is that no loss statistics are possible + */ + mclcb->congestion_control = NO_CC; /* no CC header */ + + val = tx_prof_tab[profile].datagram_sz; + err = mcl_ctl2(mclcb, MCL_OPT_DATAGRAM_SIZE, (void*)&val, sizeof(val)); + if (err) goto error; + dval = tx_prof_tab[profile].tx_rate; + err = mcl_ctl2(mclcb, MCL_OPT_TX_RATE, (void*)&dval, sizeof(dval)); + if (err) goto error; + /* above tx rate specification is only valid if a single + * layer is specified in tx_prof_tab[], otherwise should + * consider the aggregated tx rate... */ + ASSERT(tx_prof_tab[profile].layer_nb == 1); + break; + + default: + PRINT_ERR((mcl_stderr, + "mcl_set_tx_profile: profile %d not recognized\n", profile)) + goto error; + } + TRACELVL(5, (mcl_stdout, "<- mcl_set_tx_profile:\n")) + return 0; + +error: + TRACELVL(5, (mcl_stdout, "<- mcl_set_tx_profile: error\n")) + return -1; +} + + +/** + * Print the current transmission profile. + */ +mcl_error_status +mcl_print_tx_profile (mcl_cb *mclcb) +{ + if (!mclcb->is_a_sender()) { + PRINT_ERR((mcl_stderr, + "<- mcl_set_tx_profile: error, only for senders\n")) + return MCL_ERROR; + } + PRINT_OUT((mcl_stdout, "TRANSMISSION PROFILE:\n")) + PRINT_OUT((mcl_stdout, "\tCongestion control protocol: %s\n", + (mclcb->congestion_control == NO_CC ? "NONE" : + (mclcb->congestion_control == RLC_CC ? "RLC" : + "FLID-SL")))) + PRINT_OUT((mcl_stdout, "\tPacket payload size: %d\n", + mclcb->get_payload_size())) + PRINT_OUT((mcl_stdout, "\tCurrent number of layers: %d\n", + mclcb->nb_layers)) + PRINT_OUT((mcl_stdout, "\tMaximum number of layers: %d\n", + mclcb->max_nb_layers)) + PRINT_OUT((mcl_stdout, "\tSingle Layer mode: %s\n", + (mclcb->single_layer_mode) ? "true" : "false")) + PRINT_OUT((mcl_stdout, "\tTransmission rates (data only, not considering ALC/UDP/IPv4/v6 headers):\n")) + mcl_print_tx_rates(mclcb); + PRINT_OUT((mcl_stdout, "\tFEC code of last object: %s, k=%d, n=%d\n", + mclcb->fec.get_fec_code_string(), + mclcb->fec.get_k(), mclcb->fec.get_n())) + PRINT_OUT((mcl_stdout, "\tFEC expansion ratio: %f\n", + mclcb->fec.get_fec_ratio())) + PRINT_OUT((mcl_stdout, "\n")) + return MCL_OK; +} + + +/** + * Prints the transmission rates for all layers. + */ +static void +mcl_print_tx_rates (mcl_cb *mclcb) +{ + INT32 i; + txlay_t *tl; + double tps; // ticks per second. + double kbits_per_du; // kilobits per DU. + + tps = mcl_periodic_timer::get_frequency(); + kbits_per_du = (double)mclcb->get_payload_size() * 8.0 / 1000.0; + for (i = 0, tl = mclcb->txlay_tab; i < mclcb->max_nb_layers; i++, tl++) { + /* ticks per second (this is an int!) */ + PRINT_OUT((mcl_stdout, "Layer %d: rate=%.2f kbps (%.2f pkts/s) \tcumul_rate=%.2f kbps\n", + i, tl->du_per_tick * kbits_per_du * tps, + tl->du_per_tick * tps, + tl->cumul_du_per_tick * kbits_per_du * tps)) + PRINT_OUT((mcl_stdout, "tps=%f, kbits_per_du=%f, du_per_tick=%f\n", + tps, kbits_per_du, tl->du_per_tick)) + if (mclcb->single_layer_mode) { + break; + } + } +} + + diff --git a/src/alc/mcl_tx_tab.cpp b/src/alc/mcl_tx_tab.cpp new file mode 100644 index 0000000..13d1c22 --- /dev/null +++ b/src/alc/mcl_tx_tab.cpp @@ -0,0 +1,417 @@ +/* $Id: mcl_tx_tab.cpp,v 1.11 2005/04/07 15:51:39 moi Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + + +/****** Public Functions ******************************************************/ + +mcl_tx_tab::mcl_tx_tab () +{ + this->txtab_head = NULL; + this->cached_txtab = NULL; + this->tot_rem = 0; +} + + +mcl_tx_tab::~mcl_tx_tab () +{ + this->free_all_txtab(); +} + + +/* + * Register a du for nb_tx transmissions on that layer. + */ +void +mcl_tx_tab::register_du (class mcl_cb *const mclcb, + du_t *du, + INT32 nb_tx) +{ + txtab_t *tt; + +#ifdef FEC + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::register_du: du=x%x (aseq=%d bseq=%d dseq=%d/%s)\n", + (int)du, du->block->adu->seq, du->block->seq, + du->seq, (du->is_fec ? "fec" : "data"))) +#else + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::register_du: du=x%x (aseq=%d bseq=%d dseq=%d)\n", + (int)du, du->block->adu->seq, du->block->seq, du->seq)) +#endif + ASSERT(mclcb && du); + if (nb_tx <= 0) { + PRINT_ERR((mcl_stderr, "mcl_tx_tab::register_du: ERROR, nb_tx(%d)<=0", nb_tx)) + mcl_exit(-1); + } + tt = this->last_txtab(); + if (tt == NULL || tt->wr_index >= NB_TXTAB_ENTRIES || tt->rem_tx != nb_tx) { + /* need a new txtab struct */ + tt = this->create_txtab(mclcb); + this->insert_txtab(mclcb, tt); + } + tt->du_tab[tt->wr_index++] = du; + tt->rem_tx = nb_tx; + this->tot_rem++; + + //printf("register du, wr_index %i, tx_index %i\n",tt->wr_index,tt->tx_index); + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::register_du:\n")) +} + + +/* + * Returns the next DU to tx for this layer or NULL. + */ +du_t * +mcl_tx_tab::get_next_du (mcl_cb *const mclcb) +{ + txtab_t *tt; + du_t *du; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::get_next_du:\n")) + ASSERT(mclcb); + if (this->tot_rem <= 0) { + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::get_next_du: NULL (empty)\n")) + return NULL; + } + /*TRACELVL(5, (mcl_stdout, " mcl_get_next_du: before: tl->cached_txtab=x%x\n", (int)tl->cached_txtab)) */ + if ((tt = this->cached_txtab) == NULL) { /* cache fault */ + if ((tt = this->get_first_ready_txtab(mclcb)) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_tx_tab::get_next_du: ERROR, null tt")) + mcl_exit(-1); + } + this->cached_txtab = tt; /* remember it */ + } + if (tt->tx_index >= tt->wr_index) { /* exhausted: move to next tt */ + if ((tt = this->get_first_ready_txtab(mclcb)) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_tx_tab::get_next_du: ERROR, null tt")) + mcl_exit(-1); + } + this->cached_txtab = tt; /* remember it */ + } + /*TRACELVL(5, (mcl_stdout, " mcl_get_next_du: after: tl->cached_txtab=x%x\n", (int)tl->cached_txtab)) */ + ASSERT(tt->tx_index < tt->wr_index); + ASSERT(tt->wr_index <= NB_TXTAB_ENTRIES && + tt->tx_index < NB_TXTAB_ENTRIES); + du = tt->du_tab[tt->tx_index]; + tt->tx_index++; + this->tot_rem--; +#ifdef FEC + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::get_next_du: du=x%x (aseq=%d bseq=%d dseq=%d/%s)\n", + (int)du, du->block->adu->seq, du->block->seq, + du->seq, (du->is_fec ? "fec" : "data"))) +#else + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::get_next_du: du=x%x (aseq=%d bseq=%d dseq=%d)\n", + (int)du, du->block->adu->seq, du->block->seq, du->seq)) +#endif + + return du; +} + + +/* + * reset the txtab for a new transmission cycle if needed. + * returns 0 if ok, < 0 if an error + */ +INT32 +mcl_tx_tab::new_tx_cycle (mcl_cb *const mclcb) +{ + txtab_t *tt; + txtab_t *tmp_tt; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::new_tx_cycle:\n")) + ASSERT(mclcb); + ASSERT(this->tot_rem == 0); + if (!(tt = this->txtab_head)) { + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::new_tx_cycle: no txtab\n")) + return -1; + } + do { + if (mclcb->delivery_mode != DEL_MODE_ON_DEMAND) { + /* in on-demand, tx for ever, otherwise decrement */ + tt->rem_tx--; + } + if (tt->rem_tx <= 0) { + /* cannot be used for tx anymore, free it */ + tmp_tt = tt; + tt = tt->next; + this->remove_txtab(tmp_tt); + free(tmp_tt); + } else { + this->tot_rem += tt->wr_index; + tt->tx_index = 0; + tt = tt->next; + } + } while (this->txtab_head && tt != this->txtab_head); + this->cached_txtab = NULL; /* reset cache */ + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::new_tx_cycle:\n")) + return 0; +} + + +/* + * adds new transmission cycles. + * returns 0 if ok, < 0 if an error + */ +INT32 +mcl_tx_tab::add_tx_cycles (mcl_cb *const mclcb, INT32 nb_cycles) +{ + txtab_t *tt; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::add_tx_cycles:\n")) + ASSERT(mclcb); + ASSERT(this->tot_rem == 0); + if (!(tt = this->txtab_head)) { + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::add_tx_cycles: no txtab\n")) + return -1; + } + do { + if (mclcb->delivery_mode != DEL_MODE_ON_DEMAND) { + /* in on-demand, tx for ever, otherwise decrement */ + tt->rem_tx += nb_cycles; + } + tt = tt->next; + } while (this->txtab_head && tt != this->txtab_head); + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::add_tx_cycles:\n")) + return 0; +} + + +/* + * look in the txtab and mark the ADU of all the DUs waiting to be sent + * as "in_txtab" + */ +void +mcl_tx_tab::mark_adus_in_txtab (mcl_cb *const mclcb) +{ + txtab_t *tt; + du_t *du; + INT32 i; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::mark_adus_in_txtab\n")) + ASSERT(mclcb); + tt = this->txtab_head; + ASSERT(tt != NULL); + do { + if (tt->wr_index > 0 && tt->tx_index < tt->wr_index) { + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::mark_adus_in_txtab: mark DUs of tt=x%x\n", (int)tt)) + for (i = 0; i + tt->tx_index < tt->wr_index; i++) { + du = tt->du_tab[tt->tx_index + i]; + /* mark this adu as "in_txtab" */ + du->block->adu->in_txtab = 1; + } + } + tt = tt->next; + } while (tt != this->txtab_head); + /* we have cycled */ + + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::mark_adus_in_txtab:\n")) + return; +} + + +/* + * free all the txtab structs for this mclcb + */ +void +mcl_tx_tab::free_all_txtab () +{ + txtab_t *tt; + + //TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::free_all_txtab:\n")) + //ASSERT(mclcb->is_a_sender()); + while ((tt = this->last_txtab()) != NULL) { + this->remove_txtab(tt); + free(tt); + } + this->cached_txtab = NULL; /* reset cache */ + //TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::free_all_txtab:\n")) +} + + +/* + * remove all adus that are in txtabs and adds the removed adus to the adu_list + */ +void +mcl_tx_tab::remove_all_adu_from_txtab (mcl_cb *const mclcb, adu_t ** adu_list) +{ + adu_t *new_adu = NULL; + INT32 j; + txtab_t *tt; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::remove_all_adu_from_txtab:\n")) + ASSERT(mclcb->is_a_sender()); + + while ((tt = this->last_txtab()) != NULL) + { + for (j=0; jdu_tab[j]!=NULL) { + if(tt->du_tab[j]->block!=NULL) { + if((new_adu = tt->du_tab[j]->block->adu )!=NULL) { + if (mclcb->tx.get_first_adu(mclcb) != NULL) + { + mclcb->tx.remove_adu(mclcb, new_adu); + } + if ( mcl_find_adu (mclcb,new_adu->seq, new_adu->FDT_instanceid,*adu_list) == NULL) + { + mcl_insert_adu (mclcb, new_adu, &(*adu_list)); + } + } + } + } + + } + this->remove_txtab(tt); + free(tt); + } + + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::remove_all_adu_from_txtab:\n")) +} + +/****** Private Functions *****************************************************/ + + +/* + * Create and init a new txtab_t struct. + */ +txtab_t * +mcl_tx_tab::create_txtab (mcl_cb *const mclcb) +{ + txtab_t *tt; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::create_txtab:\n")) + if (!(tt = (txtab_t*)calloc(1, sizeof(txtab_t)))) { + PRINT_ERR((mcl_stderr, "mcl_tx_tab::create_txtab: ERROR, no memory")) + mcl_exit(-1); + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::create_txtab: return x%x\n", (int)tt)) + return (tt); +} + + +/* + * Insert the txtab list (one or more txtab) at the end of the list. + * Returns 1 if list was empty, 0 otherwise. + */ +INT32 +mcl_tx_tab::insert_txtab (mcl_cb *const mclcb, + txtab_t *tt) +{ + txtab_t *ptt, *ntt; /* insert tt between prev_tt, next_tt */ + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::insert_txtab:\n")) + ASSERT(tt) + ptt = this->last_txtab(); /* last txtab in list */ + if (ptt == NULL) { + /* + * first txtab in list + */ + this->txtab_head = tt; + if (!tt->next) { + /* single txtab to add */ + ASSERT((!tt->prev)) + tt->next = tt->prev = tt; + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::insert_txtab: return 1\n")) + return 1; + } + ntt = ptt->next; /* this is the following txtab in list */ + if (!tt->next) { + /* single txtab to add */ + ASSERT((!tt->prev)) + ptt->next = tt; + tt->prev = ptt; + tt->next = ntt; + ntt->prev = tt; + } else { + /* tt is a txtab list */ + ASSERT((tt->prev)) + ptt->next = tt; + (tt->prev)->next = ntt; + ntt->prev = (tt->prev); + tt->prev = ptt; + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::insert_txtab: return 0\n")) + return 0; +} + + +/* + * Remove this txtab (there's only one) from the list. + */ +void +mcl_tx_tab::remove_txtab (txtab_t *tt) +{ + //TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::remove_txtab:\n")) + ASSERT(tt); +#ifdef DEBUG + { + /* check that tt is in list (start from the end) */ + txtab_t *ltt; + for (ltt = this->last_txtab(); + ltt != NULL && ltt != tt && ltt != this->txtab_head; + ltt = ltt->prev); + ASSERT(ltt == tt); + } +#endif /* DEBUG */ + /* found, remove it */ + ASSERT((tt->prev)) + ASSERT((tt->next)) + if (this->txtab_head == tt) { + if (tt->next != tt) { + ASSERT(tt->prev != tt); + this->txtab_head = tt->next; + } else { + ASSERT(tt->prev == tt); + this->txtab_head = NULL; + } + } + tt->prev->next = tt->next; + tt->next->prev = tt->prev; + //TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::remove_txtab:\n")) +} + + +/* + * Returns the txtab found (if any), NULL if nothing is available. + */ +txtab_t * +mcl_tx_tab::get_first_ready_txtab (mcl_cb *const mclcb) +{ + txtab_t *tt; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_tab::get_first_ready_txtab:\n")) + tt = this->txtab_head; + ASSERT(tt != NULL); + do { + if (tt->wr_index > 0 && tt->tx_index < tt->wr_index) { + ASSERT(tt->wr_index <= NB_TXTAB_ENTRIES && + tt->tx_index < NB_TXTAB_ENTRIES); + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::get_first_ready_txtab: found tt=x%x\n", (int)tt)) + return tt; + } + tt = tt->next; + } while (tt != this->txtab_head); + /* we have cycled */ + TRACELVL(5, (mcl_stdout, "<- mcl_tx_tab::get_first_ready_txtab: NULL (cycled)\n")) + return NULL; +} + diff --git a/src/alc/mcl_tx_tab.h b/src/alc/mcl_tx_tab.h new file mode 100644 index 0000000..e9924cb --- /dev/null +++ b/src/alc/mcl_tx_tab.h @@ -0,0 +1,167 @@ +/* $Id: mcl_tx_tab.h,v 1.8 2005/04/07 15:51:39 moi Exp $ */ +/* + * Copyright (c) 1999-2003 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_TX_TAB_H /* { */ +#define MCL_TX_TAB_H + + +/* + * Table of planned transmissions on a layer. + * Each struct contains at most NB_TXTAB_ENTRIES each, and more struct follow + * if required. All DUs of a txtab are sent the same number of times. + */ +#define NB_TXTAB_ENTRIES 1000 +typedef struct txtab { + struct txtab *prev, *next; + UINT32 wr_index; /* index of next free DU in txtab */ + UINT32 tx_index; /* index of next DU to send in txtab */ + INT32 rem_tx; /* remaining number of tx for each du */ + du_t *du_tab[NB_TXTAB_ENTRIES]; /* table of DUs to send */ +} txtab_t; + + +/** + * Class defining the transmission plannification service at a sender. + * There is an instance of this class for normal priority ADUs, and another + * one for high priority ADUs. + */ +class mcl_tx_tab { + +public: + /****** Public Members ************************************************/ + /** Default constructor. */ + mcl_tx_tab (); + + /** Default destructor. */ + ~mcl_tx_tab (); + + /** + * Register a du for nb_tx transmissions on that layer. + * @param mclcb + * @param du DU to register + * @param nb_tx Desired number of transmissions for this DU. + * This parameter is registered in the entry + * associated with this DU and is decremented + * after each transmission (unless we are in + * ON-DEMAND mode). + */ + void register_du (class mcl_cb *const mclcb, du_t *du, INT32 nb_tx); + + /** + * Returns the next DU to tx for this layer or NULL. + * @param mclcb + * @return + */ + du_t* get_next_du (class mcl_cb *const mclcb); + + + /** + * adds new transmission cycles. + * @return 0 if ok, < 0 if an error + */ + INT32 add_tx_cycles (mcl_cb *const mclcb, INT32 nb_cycles); + + /** + * Reset the txtab for a new transmission cycle in on demand + * delivery mode. + * @return returns 0 if ok, < 0 if an error + */ + int new_tx_cycle (class mcl_cb *const mclcb); + + /** + * Look in the txtab and mark the ADU of all the DUs waiting to be sent + * as "in_txtab". + * @param mclcb + */ + void mark_adus_in_txtab (class mcl_cb *const mclcb); + + /** + * Free all the txtab structs for this mclcb. + */ + void free_all_txtab (); + + /** + * remove all adus that are in txtabs + * and adds the removed adus to the adu_list + * @param mclcb + * @param adu_list + */ + void remove_all_adu_from_txtab (mcl_cb *const mclcb, adu_t ** adu_list); + + /****** Public Attributes *********************************************/ + + int tot_rem; /* number of DUs remaining to be sent */ + + +private: + /****** Private Members ***********************************************/ + + /** + * Create and init a new txtab_t struct. + * @param mclcb + */ + txtab_t * create_txtab (mcl_cb *const mclcb); + + /** + * Insert the txtab list (one or more txtab) at the end of the list. + * Returns 1 if list was empty, 0 otherwise. + * @param mclcb + */ + int insert_txtab (mcl_cb *const mclcb, txtab_t *tt); + + /** + * Remove this txtab (there's only one) from the list. + */ + void remove_txtab (txtab_t *tt); + + /** + * Returns the txtab found (if any), NULL if nothing is available. + * @param mclcb + */ + txtab_t * get_first_ready_txtab (mcl_cb *const mclcb); + + /** + * Get last element in txtab. + */ + txtab_t * last_txtab (); + + + /****** Private Attributes ********************************************/ + + txtab_t *txtab_head; /* tx plannification table */ + txtab_t *cached_txtab; /* next DU to transmit belongs to */ + /* this txtab */ +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +inline txtab_t * +mcl_tx_tab::last_txtab () +{ + return ((this->txtab_head) ? ((this->txtab_head)->prev) : NULL); +} + + +#endif /* } MCL_TX_TAB_H */ diff --git a/src/alc/mcl_vrmem.cpp b/src/alc/mcl_vrmem.cpp new file mode 100644 index 0000000..72081bb --- /dev/null +++ b/src/alc/mcl_vrmem.cpp @@ -0,0 +1,519 @@ +/* $Id: mcl_vrmem.cpp,v 1.8 2005/05/17 12:36:58 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * This file implements a "virtual memory service" where received data + * (ie. data and FEC DUs received) is stored on disk. + * Shared by all mcl contexts. + * Data in physical memory is a "read-only" version of data on file. + * + * LIMITATIONS: + * - single very large file, located by default in /tmp. don't forget to + * change default location if not enough room there. + * - there is no possibility to remove a part of the file (eg. once an ADU + * has been completely received and returned to the application). + * The only possibility is to remove the whole file! + */ + +#include "mcl_includes.h" + + +#ifdef VIRTUAL_RX_MEM + +/****** Public Functions ******************************************************/ + +/** + * Constructor. + * => See header file for more informations. + */ +mcl_vrmem::mcl_vrmem () +{ + /* not fully initialized yet, in particular the vrmem file has + * not yet been allocated... */ + this->initialized = false; + memset(this->vrfile_name, 0, sizeof(this->vrfile_name)); + this->vrfile_fd = 0; + this->vrfile_len = 0; + this->vrbuf_max_size = VIRTUAL_RX_MEM_MAX_BUFFERING_SIZE; + this->vrbuf_size = 0; + this->in_vrbuf_list_head = NULL; +} + + +/** + * Destructor. + * => See header file for more informations. + */ +mcl_vrmem::~mcl_vrmem () +{ + if (this->initialized) + this->close(NULL); + this->initialized = false; + memset(this->vrfile_name, 0, sizeof(this->vrfile_name)); + this->vrfile_fd = 0; + this->vrfile_len = 0; + this->vrbuf_max_size = VIRTUAL_RX_MEM_MAX_BUFFERING_SIZE; + this->vrbuf_size = 0; + this->in_vrbuf_list_head = NULL; +} + + +/** + * => See header file for more informations. + */ +mcl_error_status +mcl_vrmem::close (mcl_cb *const mclcb) +{ + if (!this->initialized) + return MCL_OK; + if (mclcb) + TRACELVL(5, (mcl_stdout, "-> mcl_vrmem::close:\n")) + this->initialized = false; + unlink(this->vrfile_name); /* remove vrmem file */ + this->vrfile_fd = 0; + if (mclcb) + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::close: ok\n")) + return MCL_OK; +} + + +/** + * => See header file for more informations. + */ +bool +mcl_vrmem::must_store_in_vrfile (mcl_cb *const mclcb, + UINT32 len) +{ + //ASSERT(mclcb->rx_storage->is_vrmem_used() == true); + TRACELVL(5, (mcl_stdout, + " mcl_vrmem::must_store_in_vrfile: vrbuf usage: sz=%Ld, max_sz=%Ld, want to store %d\n", + this->vrbuf_size, this->vrbuf_max_size, len)) + if (this->vrbuf_size + len <= this->vrbuf_max_size) { + TRACELVL(5, (mcl_stdout, + "<- mcl_vrmem::must_store_in_vrfile: no, there's room in vrbuf\n")) + return false; + } else { + TRACELVL(5, (mcl_stdout, + "<- mcl_vrmem::must_store_in_vrfile: yes\n")) + return true; + } +} + + +/** + * => See header file for more informations. + */ +mcl_error_status +mcl_vrmem::store_in_vrfile (mcl_cb *const mclcb, + du_t *du) +{ + INT64 off; /* offset */ + INT32 err; + + TRACELVL(5, (mcl_stdout, "-> mcl_vrmem::store_in_vrfile:\n")) + //ASSERT(mclcb->rx_storage->is_vrmem_used() == true); + if (!this->initialized) + this->finish_init(mclcb); + ASSERT(du); + ASSERT(du->pkt); + ASSERT(du->data); + ASSERT(du->len > 0); + if (du->vrm_info.status == STORAGE_STATUS_ONLY_IN_VRBUF) { + /* unregister from vrbuf */ + this->vrbuf_size -= du->len; + ASSERT(this->vrbuf_size >= 0); + /* remove this DU from the list of DUs in _IN_VRBUF_ state */ + this->remove_from_vrbuf_list (mclcb, du); + } else { + ASSERT(du->vrm_info.status == STORAGE_STATUS_INVALID); + } + du->vrm_info.status = STORAGE_STATUS_ONLY_IN_VRFILE; + off = du->vrm_info.off = this->vrfile_len; + this->vrfile_len += du->len; + /* repositionning within file is absolutely required! */ + if (mcl_file_lseek(this->vrfile_fd, off) < 0) { + perror("mcl_vrmem::store_in_vrfile: ERROR: lseek failed\n"); + goto error; + } + /* store data */ + if ((err = mcl_file_write(this->vrfile_fd, du->data, du->len)) < 0) { + perror("mcl_vrmem::store_in_vrfile: ERROR: write failed\n"); + goto error; + } + /* remove buffer now */ + delete du->pkt; + du->pkt = NULL; + du->data = NULL; + TRACELVL(5, (mcl_stdout, + "<- mcl_vrmem::store_in_vrfile: starts at off=%Ld\n", off)) + return MCL_OK; + +error: + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::store_in_vrfile: ERROR\n")) + return MCL_ERROR; +} + + +/** + * The vrbuf copy is newer than the vrfile copy, so update + * the permanent repository (similar to a cache entry with + * the "dirty bit" set). + * => See header file for more informations. + */ +mcl_error_status +mcl_vrmem::update_vrfile_from_dirty_vrbuf (class mcl_cb *const mclcb, + struct du *du) +{ + INT64 off; /* offset */ + INT32 err; + + TRACELVL(5, (mcl_stdout, "-> mcl_vrmem::update_vrfile_from_dirty_vrbuf:\n")) + ASSERT(this->initialized); + ASSERT(du); + ASSERT(du->pkt); + ASSERT(du->data); + ASSERT(du->len > 0); + if (du->vrm_info.status != STORAGE_STATUS_IN_VRFILE_AND_VRBUF) { + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::update_vrfile_from_dirty_vrbuf: nothing to do, bad status (%d)\n", du->vrm_info.status)) + return MCL_OK; + } + off = du->vrm_info.off; + /* repositionning within file is absolutely required! */ + if (mcl_file_lseek(this->vrfile_fd, off) < 0) { + perror("mcl_vrmem::update_vrfile_from_dirty_vrbuf: ERROR: lseek failed\n"); + goto error; + } + /* store data */ + if ((err = mcl_file_write(this->vrfile_fd, du->data, du->len)) < 0) { + perror("mcl_vrmem::update_vrfile_from_dirty_vrbuf: ERROR: write failed\n"); + goto error; + } + TRACELVL(5, (mcl_stdout, + "<- mcl_vrmem::update_vrfile_from_dirty_vrbuf:\n")) + return MCL_OK; + +error: + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::update_vrfile_from_dirty_vrbuf: ERROR\n")) + return MCL_ERROR; + +} + + +/** + * => See header file for more informations. + */ +mcl_error_status +mcl_vrmem::get_from_vrfile (mcl_cb *const mclcb, + du_t *du) +{ + UINT32 len; + + TRACELVL(5, (mcl_stdout, "-> mcl_vrmem::get_from_vrfile:\n")) + //ASSERT(mclcb->rx_storage->is_vrmem_used() == true); + ASSERT(this->initialized); + ASSERT(du->vrm_info.status == STORAGE_STATUS_ONLY_IN_VRFILE); + /* remove as many buffers already allocated (usually one is enough), + * as long as vrbuf_size + len > max_vrbuf_size */ + while (this->vrbuf_size + du->len > this->vrbuf_max_size) { + du_t *this_one = this->in_vrbuf_list_head; + if (this_one->vrm_info.status == + STORAGE_STATUS_IN_VRFILE_AND_VRBUF) { + this->remove_from_vrbuf(mclcb, this_one); + } else { + ASSERT(this_one->vrm_info.status == + STORAGE_STATUS_ONLY_IN_VRBUF); + this->store_in_vrfile(mclcb, this_one); + } + /* update stats */ + mclcb->stats.buf_space -= this_one->len; + } + /* update the vrbuf list size */ + this->vrbuf_size += du->len; + /* update the storage status */ + du->vrm_info.status = STORAGE_STATUS_IN_VRFILE_AND_VRBUF; + /* add this DU to the list of DUs in _IN_VRBUF_ state */ + this->add_to_end_of_vrbuf_list(mclcb, du); + /* and read data from disk */ + /* repositionning within file is absolutely required! */ + if (mcl_file_lseek(this->vrfile_fd, du->vrm_info.off) < 0) { + perror("mcl_vrmem::get_from_vrfile: ERROR: lseek failed\n"); + goto error; + } + if ((len = mcl_file_read(this->vrfile_fd, du->data, du->len)) <= 0 || + len != du->len) { + perror("mcl_vrmem::get_from_vrfile: ERROR: read failed\n"); + goto error; + } + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::get_from_vrfile:\n")) + return MCL_OK; + +error: + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::get_from_vrfile: ERROR\n")) + return MCL_ERROR; +} + + +/** + * Removes data from disk for this DU. + */ +mcl_error_status +mcl_vrmem::remove_from_vrfile (class mcl_cb *const mclcb, + struct du *du) +{ + ASSERT(du); + TRACELVL(5, (mcl_stdout, " mcl_vrmem::remove_from_vrfile:\n")) + ASSERT(du->vrm_info.status == STORAGE_STATUS_ONLY_IN_VRFILE); + du->vrm_info.status = STORAGE_STATUS_INVALID; + return MCL_OK; +} + + +/** + * => See header file for more informations. + */ +void +mcl_vrmem::register_in_vrbuf (mcl_cb *const mclcb, + du_t *du) +{ + ASSERT(du); + ASSERT(du->len > 0); + TRACELVL(5, (mcl_stdout, "-> mcl_vrmem::register_in_vrbuf: len=%d\n", + du->len)) + /* update the vrbuf list size */ + this->vrbuf_size += du->len; + //ASSERT(this->vrbuf_size <= this->vrbuf_max_size); + /* update the storage status */ + ASSERT(du->vrm_info.status == STORAGE_STATUS_INVALID); + du->vrm_info.status = STORAGE_STATUS_ONLY_IN_VRBUF; + /* add this DU to the list of DUs in _IN_VRBUF_ state */ + this->add_to_end_of_vrbuf_list(mclcb, du); + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::register_in_vrbuf:\n")) +} + + +/** + * => See header file for more informations. + */ +void +mcl_vrmem::remove_from_vrbuf (mcl_cb *const mclcb, + du_t *du) +{ + ASSERT(du); + ASSERT(du->len > 0); + TRACELVL(5, (mcl_stdout, "-> mcl_vrmem::remove_from_vrbuf: len=%d\n", + du->len)) + /* remove this DU from the list of DUs in _IN_VRBUF_ state */ + this->remove_from_vrbuf_list (mclcb, du); + /* update the vrbuf list size */ + this->vrbuf_size -= du->len; + ASSERT(this->vrbuf_size >= 0); + /* update the storage status */ + if (du->vrm_info.status == STORAGE_STATUS_IN_VRFILE_AND_VRBUF) { + du->vrm_info.status = STORAGE_STATUS_ONLY_IN_VRFILE; + } else { + ASSERT(du->vrm_info.status == STORAGE_STATUS_ONLY_IN_VRBUF); + du->vrm_info.status = STORAGE_STATUS_INVALID; + } + /* remove buffer now */ + ASSERT(du->pkt); + delete du->pkt; + du->pkt = NULL; + du->data = NULL; + TRACELVL(5, (mcl_stdout, + "<- mcl_vrmem::remove_from_vrbuf: remains %Ld\n", + this->vrbuf_size)) +} + + +/** + * => See header file for more informations. + */ +bool +mcl_vrmem::in_vrfile (class mcl_cb *const mclcb, + du_t *du) +{ + ASSERT(du); + if ((du->vrm_info.status == STORAGE_STATUS_ONLY_IN_VRFILE) || + (du->vrm_info.status == STORAGE_STATUS_IN_VRFILE_AND_VRBUF)) { + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::in_vrfile: yes\n")) + return true; + } else { + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::in_vrfile: no\n")) + return false; + } +} + + +/** + * => See header file for more informations. + */ +bool +mcl_vrmem::in_vrbuf (class mcl_cb *const mclcb, + struct du *du) +{ + ASSERT(du); + if ((du->vrm_info.status == STORAGE_STATUS_ONLY_IN_VRBUF) || + (du->vrm_info.status == STORAGE_STATUS_IN_VRFILE_AND_VRBUF)) { + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::in_vrbuf: yes\n")) + return true; + } else { + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::in_vrbuf: no\n")) + return false; + } +} + + +/****** Private Functions *****************************************************/ + + +/** + * Finish the initialization. + * => See header file for more informations. + */ +mcl_error_status +mcl_vrmem::finish_init (mcl_cb *const mclcb) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_vrmem::finish_init:\n")) + ASSERT(this->initialized == false); +#if 0 + vcb->entry_size = mclcb->datagram_sz; /* fixed size! */ + if (!(pm_tab = (vrm_cache_entry_t*)calloc(mcl_vrm_cache_entry_nb, + sizeof(vrm_cache_entry_t))) || + !(pm_blk = (char*)malloc(mcl_vrm_cache_entry_nb * vcb->entry_size))) + { + PRINT_ERR((mcl_stderr,"mcl_vrmem::finish_init: ERROR: out of memory")) + goto error; + } + for (i = 0, pm = pm_tab, off = 0; + i < (int)mcl_vrm_cache_entry_nb; + i++, pm++, off += vcb->entry_size) { + pm->data = pm_blk + off; + } + vcb->entry_nb = mcl_vrm_cache_entry_nb; + vcb->pmem_tab = pm_tab; + vcb->next_index = 0; +#endif + + /* create temp file now in the tmp dir specified in mcl_tmp_dir_name */ +#ifdef WIN32 + /* create the filename string first */ +#ifdef VIRTUAL_RX_MEM_SINGLE_RECEIVER_PER_HOST_MODE + strncpy(this->vrfile_name, mcl_tmp_dir_name, MAX_FILE_NAME_LEN); + strncat(this->vrfile_name, "mcl_vrm_tmpfile", MAX_FILE_NAME_LEN); +#else + strncpy(this->vrfile_name, tempnam(mcl_tmp_dir_name, "mcl_vrm_tmpfile_"), + MAX_FILE_NAME_LEN); +#endif + /* then open the file, using in particular the LARGEFILE flag */ + if ((this->vrfile_fd = mcl_file_open(this->vrfile_name, _O_RDWR | O_CREAT | O_BINARY, 0)) < 0) { + perror("mcl_vrmem::finish_init: ERROR"); + goto error; + } +#else /* UNIX case */ + /* create the filename string first */ + strncpy(this->vrfile_name, mcl_tmp_dir_name, MAX_FILE_NAME_LEN); +#ifdef VIRTUAL_RX_MEM_SINGLE_RECEIVER_PER_HOST_MODE + strncat(this->vrfile_name, "mcl_vrm_tmpfile", MAX_FILE_NAME_LEN); +#else + strncat(this->vrfile_name, "mcl_vrm_tmpfile_", MAX_FILE_NAME_LEN); + char pid_str[10]; + memset(pid_str, '0', strlen(pid_str)); + snprintf(pid_str, 9, "%d", (INT32)getpid()); + strncat(this->vrfile_name, pid_str, MAX_FILE_NAME_LEN); +#endif +#ifdef __USE_LARGEFILE64 + /* then open the file, using in particular the LARGEFILE flag */ + if ((this->vrfile_fd = mcl_file_open(this->vrfile_name, + O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, + S_IRWXU)) < 0) { + perror("mcl_vrmem::finish_init: ERROR"); + goto error; + } +#else /* ! __USE_LARGEFILE64 */ + if ((this->vrfile_fd = mcl_file_open(this->vrfile_name, + O_RDWR | O_CREAT | O_TRUNC, + S_IRWXU)) < 0) { + perror("mcl_vrmem::finish_init: ERROR"); + goto error; + } +#endif /* __USE_LARGEFILE64 */ +#endif /* OS */ + this->initialized = 1; + TRACELVL(5, (mcl_stdout, "<- mcl_vrmem::finish_init:\n")) + return MCL_OK; + +error: + TRACELVL(5, (mcl_stdout, "mcl_vrmem::finish_init: ERROR\n")) + return MCL_ERROR; +} + + +/** + * Add this DU to the end of the list of DUs in _IN_VRBUF_ state. + */ +void +mcl_vrmem::add_to_end_of_vrbuf_list (class mcl_cb *const mclcb, + struct du *du) +{ + TRACELVL(5, (mcl_stdout, " mcl_vrmem::add_to_end_of_vrbuf_list:\n")) + if (this->in_vrbuf_list_head == NULL) { + /* empty list */ + this->in_vrbuf_list_head = du; + du->vrm_info.prev_in_vrbuf = du->vrm_info.next_in_vrbuf = du; + } else { + /* add it to the end of list */ + du_t *tail = this->in_vrbuf_list_head->vrm_info.prev_in_vrbuf; + du->vrm_info.prev_in_vrbuf = tail; + tail->vrm_info.next_in_vrbuf = du; + du->vrm_info.next_in_vrbuf = this->in_vrbuf_list_head; + this->in_vrbuf_list_head->vrm_info.prev_in_vrbuf = du; + } +} + + +/** + * Remove this DU from the list of DUs in _IN_VRBUF_ state. + */ +void +mcl_vrmem::remove_from_vrbuf_list (class mcl_cb *const mclcb, + struct du *du) +{ + du_t *prev = du->vrm_info.prev_in_vrbuf; + du_t *next = du->vrm_info.next_in_vrbuf; + + TRACELVL(5, (mcl_stdout, " mcl_vrmem::remove_from_vrbuf_list:\n")) + if (prev == du) { + /* du is the only one in list */ + ASSERT(next == du); + this->in_vrbuf_list_head = NULL; + } else { + prev->vrm_info.next_in_vrbuf = next; + next->vrm_info.prev_in_vrbuf = prev; + if (this->in_vrbuf_list_head == du) { + /* du was the first in list */ + this->in_vrbuf_list_head = next; + } + } + du->vrm_info.prev_in_vrbuf = du->vrm_info.next_in_vrbuf = NULL; +} + + +#endif /* VIRTUAL_RX_MEM */ diff --git a/src/alc/mcl_vrmem.h b/src/alc/mcl_vrmem.h new file mode 100644 index 0000000..c935f2e --- /dev/null +++ b/src/alc/mcl_vrmem.h @@ -0,0 +1,329 @@ +/* $Id: mcl_vrmem.h,v 1.6 2005/05/17 12:36:59 roca Exp $ */ +/* + * Copyright (c) 2005 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * "virtual receive memory service" + * + * This file implements a "virtual memory service" where incoming data + * (ie. data and FEC DUs received or decoded) is stored either in memory + * and/or on disk, so that at any time the total size of buffers (ie. data + * in memory) does not exceed a certain threshold. + * + * TERMINOLOGY: + * - vrmem virtual receive memory service: this is the service + * - vrbuf vrmem buffer: this is the vrmem set of buffers, in RAM + * The total size of buffers is of course limited. + * - vrfile vrmem file: this is the vrmem big file, on the disk + * + * LIMITATIONS: + * - single very large file, located by default in /tmp. Don't forget to + * change default location if not enough room there. + * - there is no possibility to remove a part of the file (eg. once an ADU + * has been completely received and returned to the application). + * The only possibility is to remove the whole file! + */ + + +#ifndef MCL_VRMEM_H /* { */ +#define MCL_VRMEM_H + +#ifdef VIRTUAL_RX_MEM + + +/** + * Storage status of a DU. + * Associated FSM: + * + * register_in_vrbuf + * INVALID --------------------------> ONLY_IN_VRBUF + * ^| <-------------------------- | + * || unregister_from_vrbuf | + * || + + * remove_from || store_in_vrfile / + * _vrfile || / + * || / store_in_vrfile + * ||+--------------------------------+ + * ||| + * |VV get_from_vrfile + * ONLY_IN_VRFILE -----------------------> IN_VRFILE_AND_VRBUF + * <----------------------- | ^ + * unregister_from_vrbuf | | + * +---------+ + * update_vrfile_from_dirty_vrbuf + */ +enum mcl_vrmem_storage_status { + STORAGE_STATUS_INVALID = 0, /* nothing stored */ + STORAGE_STATUS_ONLY_IN_VRBUF, /* only in memory buffer */ + STORAGE_STATUS_ONLY_IN_VRFILE, /* only in file, nothing in mem buf */ + STORAGE_STATUS_IN_VRFILE_AND_VRBUF /* permanently stored in vrfile */ + /* with a copy available in mem buf */ +}; + + +/** + * DU <=> vrmem correspondance. + * Stored in the du_t structure. + */ +typedef struct vrmem_info { + mcl_vrmem_storage_status status; /* DU storage status */ + INT64 off; /* DU offset in vrfile. Only */ + /* valid in *_VRFILE_* states */ + struct du *prev_in_vrbuf; /* Pointer to previous DU in */ + /* *_IN_VRBUF_* state */ + struct du *next_in_vrbuf; /* Pointer to next DU in */ + /* *_IN_VRBUF_* state */ +} vrmem_info_t; + + +#if 0 +/* + * Describes each buffer of the vrbuf system. + * Managed as a single table of vrmem_buf_entry_t structs in practice. + * The buffer associated to a DU is the mcl_rx_pkt object, du->pkt. + */ +typedef struct { + //char *data; /* data block of this entry */ + struct du *du; /* owner of this entry */ +} vrmem_buf_entry_t; +#endif + + +/** + * This Class implements the Virtual Receive Memory service. + */ +class mcl_vrmem { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + mcl_vrmem (); + + /** + * Default destructor. + */ + ~mcl_vrmem (); + + /** + * Frees the vrmem file and closes the service. + * @param mclcb + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status close (class mcl_cb *const mclcb); + + /** + * Must we use the vrmem file to actually store data? + * This is only possible if the vrmem service is used and there's + * no room any more in the vrmem buffer. + * @param mclcb + * @param len data size. + * @return true if vrfile must be used, false if it is + * possible to use the vrbuf. + */ + bool must_store_in_vrfile (class mcl_cb *const mclcb, + UINT32 len); + + /** + * Stores data of the DU in the vrmem file, unregisters (if + * needed) and free's the buffer. + * Data is stored in arrival order in vrfile order to maximize the + * write-to-disk speed. + * Data is assumed to be in du->data and du->pkt, but this buffer + * will be free'd by this function. Even if data is in du->data, + * the state upon calling this function can either be INVALID + * (ie. not registered in vrbuf) or ONLY_IN_VRBUF (ie. already + * registered in vrbuf). + * @param mclcb + * @param du DU associated to the data buffer. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status store_in_vrfile + (class mcl_cb *const mclcb, + struct du *du); + + /** + * The vrbuf copy is newer than the vrfile copy, so update + * the permanent repository (similar to a cache entry with + * the "dirty bit" set). + * Only valid in IN_VRFILE_AND_VRBUF state, does nothing in + * other states. + * @param mclcb + * @param du DU associated to the dirty data buffer. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status update_vrfile_from_dirty_vrbuf + (class mcl_cb *const mclcb, + struct du *du); + + /** + * Retrieves data from disk for this DU and copies it to the + * buffer pointed by du->data. + * A rx_pkt buffer must already be allocated, du->pkt and du->data + * must be set accordingly. + * @param mclcb + * @param du DU associated to the data buffer. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status get_from_vrfile + (class mcl_cb *const mclcb, + struct du *du); + + /** + * Removes data from disk for this DU. + * @param mclcb + * @param du DU associated to the data buffer. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status remove_from_vrfile + (class mcl_cb *const mclcb, + struct du *du); + + /** + * Register this DU in the vrmem buffer system. + * There is no additional data copy nor buffer allocation, this + * function only takes into account that len additional bytes are + * stored in RAM. + * Used later on by must_store_in_vrfile() to know if new data + * packets can be kept in RAM or must be stored in vrmem file. + * @param mclcb + * @param du DU associated to the buffer. + */ + void register_in_vrbuf (class mcl_cb *const mclcb, + struct du *du); + + /** + * Removes this DU from the vrmem buffer system, and free's + * the associated buffer. + * @param mclcb + */ + void remove_from_vrbuf (class mcl_cb *const mclcb, + struct du *du); + + /** + * Returns true if this DU is stored in the vrfile. + * @param mclcb + * @return true if data is in vrfile. + */ + bool in_vrfile (class mcl_cb *const mclcb, + struct du *du); + + /** + * Returns true if this DU is stored in the vrbuf. + * @param mclcb + * @return true if data is in vrbuf. + */ + bool in_vrbuf (class mcl_cb *const mclcb, + struct du *du); + + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + + /** + * Finishes the initialization of the vrmem service. + * The vrmem file is now allocated. + * This call should happen only when one is about to use the vrmem + * file to avoid extra processing. + * @param mclcb + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status finish_init (class mcl_cb *const mclcb); + + + /** + * Add this DU to the end of the list of DUs in _IN_VRBUF_ state. + * Performs only the various pointer updates. + * @param mclcb + * @param du DU to add at the end of list. + */ + void add_to_end_of_vrbuf_list (class mcl_cb *const mclcb, + struct du *du); + + /** + * Remove this DU from the list of DUs in _IN_VRBUF_ state. + * Performs only the various pointer updates. + * @param mclcb + * @param du DU to remove. + */ + void remove_from_vrbuf_list (class mcl_cb *const mclcb, + struct du *du); + + + /****** Private Attributes ********************************************/ + + /** + * True once the vrmem service has been fully initialized, and + * in particular the vrmem file created. + * This happens once initialize() has been called. + */ + bool initialized; + + /* + * vrmem file info. + */ + /** vrmem file name. */ + char vrfile_name[MAX_FILE_NAME_LEN]; + /** vrmem file fd. */ + INT32 vrfile_fd; + /** current vrmem file length. */ + INT64 vrfile_len; + + /* + * vrmem buffer info. + */ + /** Maximum vrmem buffer size possible before using the vrmem file. */ + INT64 vrbuf_max_size; + /** Total physical receive memory buffer allocated. */ + INT64 vrbuf_size; + /** + * Start of the doubly linked list of DUs with _IN_VRBUF_ state. + * This list is used to swap to disk some DUs when room is needed + * by a get_from_vrfile() call. + */ + struct du *in_vrbuf_list_head; +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +#if 0 +inline bool +mcl_vrmem::on_disk (class mcl_cb *const mclcb, + struct du *du) +{ + ASSERT(du); + //TRACELVL(5, (mcl_stdout, " mcl_vrmem::on_disk: %d\n", du->vrm_info.on_disk)) +printf("%d\n", du->len); + //return du->vxm.r_info_u.on_disk; + return du->vrm_info.on_disk; +} +#endif + + +#endif /* VIRTUAL_RX_MEM */ + +#endif /* } MCL_VRMEM_H */ diff --git a/src/alc/mcl_vtmem.cpp b/src/alc/mcl_vtmem.cpp new file mode 100644 index 0000000..5c92f4b --- /dev/null +++ b/src/alc/mcl_vtmem.cpp @@ -0,0 +1,525 @@ +/* $Id: mcl_vtmem.cpp,v 1.4 2005/01/11 13:12:37 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * This file implements a "virtual memory service" where data (ie. ADUs and + * FEC DUs) is stored on disk and copied in physical memory when required. + * Data in physical memory is a "read-only" version of data on file. + * We also have the possibility to store data in physical memory (ptm) untill + * a predefined threshold is reached. Above it, data is stored in vtm. + * + * +---------+ +---------+ +-----------+ + * | on disk | store | phy mem | | phy mem | + * | (vtm) | <---- | cache | | buf (ptm) | + * | no size | ----> | size | | size | + * | limit! | page | limit | | limit | + * +---------+ fault +---------+ +-----------+ + * \---------------------------/ \-----------/ + * virtual tx mem service keep in memory + * + * + * LIMITATIONS: + * - the disk file is shared by all mcl contexts. + * - there is a single very large file, located by default in /tmp. Do + * not forget to change default location if there isn't enough room there. + * - there is no possibility to remove a part of the file (eg. once all + * the DUs of an ADU have been sent. The only possibility is to remove + * the whole file which can only happen if all ADUs (!) have been totally + * sent. + */ + +#include "mcl_includes.h" + + +#ifdef VIRTUAL_TX_MEM + +/* + * by default create that nb of phy mem. + * NB: there should be enough phy mem entries to store all DUs of a block! + * required by the current FEC codec + */ +u_int mcl_vtm_cache_entry_nb = 256; + + +/* + * private functions + */ +static void mcl_vtm_initialize (mcl_cb *mclcb); +static vtm_cache_entry_t* mcl_find_empty_slot (mcl_cb *mclcb, int seq); +#ifdef NEVERDEF +static int mcl_find_position_on_disk (mcl_cb *mclcb, du_t *du); +#else +#define mcl_find_position_on_disk(mcl_cb,du) (du)->vtm_info.off +#endif +static int mcl_copy_from_disk (mcl_cb *mclcb, du_t *du, int from_fd, + int from_off, vtm_cache_entry_t *to, + int seq); +static vtm_cache_entry_t* mcl_find_du_in_vtm_cache (mcl_cb *mclcb, du_t *du); + + +/****** Public Functions ******************************************************/ + + +/* + * Can we use the vtm service to actually store data? + * This is only possible if vtm service is used and there's no room + * any more in the ptm area. + * returns a flag: 1 if positive, 0 otherwise + */ +int +mcl_vtm_can_store_in_vtm (mcl_cb *mclcb, + int len) /* buffer length */ +{ + vtm_cb_t *vcb; /* vtm control block ptr */ + + ASSERT(mcl_cb); + if (!mclcb->vtm_used) { + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_can_store_in_vtm: vtm not used\n")) + return 0; + } + if (!mclcb->vtm_initialized) + mcl_vtm_initialize(mcl_cb); + vcb = &(mcl_cb->vtm_cb); + if (vcb->ptm_size + len <= vcb->max_ptm_size) { + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_can_store_in_vtm: no, room in ptm\n")) + return 0; + } else { + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_can_store_in_vtm: yes\n")) + return 1; + } +} + + +/* + * Stores data of the ADU (if not NULL) or DU (if not NULL) in the vtm + * service. + * Store only in file, never in the phy mem entries, as doing so would be + * most of the time useless. + * returns 0 if OK, < 0 if error + */ +int +mcl_vtm_store_data (mcl_cb *mclcb, + adu_t *adu, /* NULL if not applicable */ + du_t *du, /* NULL if not applicable */ + char *data, /* buffer */ + int len, /* buffer length */ + int padded_len) /* required with adu, or 0 */ +{ + u_int off; /* offset */ + int l; + char *pad; /* padding buffer */ + vtm_cb_t *vcb = &(mcl_cb->vtm_cb); /* vtm control block ptr */ + + ASSERT(mcl_cb); + ASSERT(mcl_cb->vtm_used); + TRACELVL(5, (mcl_stdout, "-> mcl_vtm_store_data:\n")) + if (!mclcb->vtm_initialized) + mcl_vtm_initialize(mcl_cb); + if (adu) { + off = adu->vtm_info.off = vcb->f_len; + adu->vtm_info.in_vtm = 1; + vcb->f_len += padded_len; + adu->data = NULL; /* not in phy mem */ + } else { + ASSERT(du); + off = du->vtm_info.off = vcb->f_len; + du->vtm_info.in_vtm = 1; + vcb->f_len += len; + du->data = NULL; /* not in phy mem */ + } + + /* repositionning within file is absolutely required! */ + if (lseek(vcb->f_fd, off, SEEK_SET) < 0) { + perror("mcl_vtm_store_data: ERROR: lseek failed"); + PRINT_ERR((mcl_stderr, "mcl_vtm_store_data: ERROR, lseek (off=%u) failed\n", off)); + PRINT_ERR((mcl_stderr, "The sending file plus the FEC symbols created are probably too large!\n")) + PRINT_ERR((mcl_stderr, "You may try to reduce the number of FEC symbols...\n")) + goto bad; + } + /* store data */ + if ((l = write(vcb->f_fd, data, len)) < 0) { + perror("mcl_vtm_store_data: ERROR: read failed"); + goto bad; + } + /* now store the NULL padding in the file */ + if (padded_len > len) { + pad = (char*)calloc(padded_len - len, 1); + if ((l = write(vcb->f_fd, pad, padded_len - len)) < 0) { + perror("mcl_vtm_store_data: ERROR: read failed"); + goto bad; + } + free(pad); + } + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_store_data: starts at off=%d\n", off)) + return 0; + +bad: + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_store_data: ERROR\n")) + mcl_exit(-1); + return -1; /* just to avoid a compiler warning! */ +} + + +/* + * Registers the offset in the vtm file for each du. + * Assumes that the actual data has already been stored with the adu + * in a previous call to mcl_vtm_store_data(). + */ +void +mcl_vtm_register_du (mcl_cb *mclcb, + du_t *du, + u_int off) +{ + ASSERT(mcl_cb); + ASSERT(du); + ASSERT(du->is_fec == false); + /* offset within vtm file */ + du->vtm_info.off = du->block->adu->vtm_info.off + off; + du->vtm_info.in_vtm = 1; /* not in ptm but in vtm! */ + du->data = NULL; /* not in phy mem */ + TRACELVL(5, (mcl_stdout, + " mcl_vtm_register_du: off=%d\n", du->vtm_info.off)) +} + + +/* + * register that this size is kept in physical memory + */ +void +mcl_vtm_register_in_ptm (mcl_cb *mclcb, + adu_t *adu, /* NULL if not applicable */ + du_t *du, /* NULL if not applicable */ + int len) /* buffer length */ +{ + ASSERT(mcl_cb); + ASSERT(len > 0); + TRACELVL(5, (mcl_stdout, " mcl_vtm_register_in_ptm:\n")) + mclcb->vtm_cb.ptm_size += len; + ASSERT(mcl_cb->vtm_cb.ptm_size <= mclcb->vtm_cb.max_ptm_size); + if (adu) { + adu->vtm_info.in_vtm = 0; /* false, it is in ptm */ + } else { + ASSERT(du); + du->vtm_info.in_vtm = 0; /* false, it is in ptm */ + } +} + + +/* + * Given a DU pointer, makes sure that the du->data pointer is a valid + * pointer, retrieving data from disk if necessary. + * In fact retrieves, when required, du->du_in_seq_in_txtab consecutive + * DUs from disk. + */ +char * +mcl_vtm_get_data (mcl_cb *mclcb, + du_t *du) +{ + vtm_cache_entry_t *to; /* put data here */ + int from_off; /* what offset on disk? */ + vtm_cb_t *vcb = &(mcl_cb->vtm_cb); /* vtm control block ptr */ + + ASSERT(mcl_cb); + TRACELVL(5, (mcl_stdout, "-> mcl_vtm_get_data:\n")) + if (du->data) { + /* data buffer is present */ + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_get_data: cached, ok\n")) + return du->data; + } + ASSERT(mcl_cb->vtm_used); + ASSERT(mcl_cb->vtm_initialized); + ASSERT(du->vtm_info.in_vtm); +#ifdef NEVERDEF + { + /* + * check that the du_in_seq_in_txtab DUs starting from du would + * create a cache fault + */ + int i; + du_t *tmp_du = du; + for (i = du->vtm_info.du_in_seq_in_txtab; i > 0; i--) { + ASSERT(tmp_du); + ASSERT(tmp_du->data == NULL); + tmp_du++; + } + } +#endif /* NEVERDEF */ + /* data is on disk, page fault, retrieve it first */ + if (!(to = mcl_find_empty_slot(mcl_cb, du->vtm_info.du_in_seq_in_txtab))) { + PRINT_ERR((mcl_stderr, + "mcl_vtm_get_data: ERROR, mcl_find_empty_slot failed\n")) + goto bad; + } + if ((from_off = mcl_find_position_on_disk(mcl_cb, du)) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_vtm_get_data: ERROR, mcl_find_position_on_disk failed\n")) + goto bad; + } + if (mcl_copy_from_disk(mcl_cb, du, vcb->f_fd, from_off, to, + du->vtm_info.du_in_seq_in_txtab)) { + PRINT_ERR((mcl_stderr, + "mcl_vtm_get_data: ERROR, mcl_copy_from_disk failed\n")) + goto bad; + } + ASSERT(to->data == du->data); + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_get_data: from disk, ok\n")) + return du->data; + +bad: + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_get_data: ERROR\n")) + mcl_exit(-1); + return NULL; /* just to avoid a compiler warning! */ +} + + +/* + * Frees the vtm file and closes the service. + * returns 0 if ok, an error code otherwise + */ +int +mcl_vtm_close (mcl_cb *mclcb) +{ + vtm_cb_t *vcb = &(mcl_cb->vtm_cb); /* vtm control block ptr */ + + if (!mclcb->vtm_initialized || !mclcb->vtm_used) + return 0; + TRACELVL(5, (mcl_stdout, "-> mcl_vtm_close:\n")) + /* XXX: add a user counter and actually close when last one leaves!!! */ + mclcb->vtm_initialized = 0; + free(vcb->pmem_tab[0].data); + vcb->pmem_tab[0].data = NULL; /* security */ + free(vcb->pmem_tab); + vcb->pmem_tab = NULL; /* security */ + close(vcb->f_fd); /* release the fd */ + unlink(vcb->f_name); /* remove VTMEM file */ + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_close: ok\n")) + return 0; +} + + +/****** Private Functions *****************************************************/ + + +/* + * initialize everything + */ +static void +mcl_vtm_initialize (mcl_cb *mclcb) +{ + vtm_cache_entry_t *pm_tab; /* table of structs */ + char *pm_blk; /* actual memory block */ + vtm_cache_entry_t *pm; /* tmp var */ + int i; + u_int off; + vtm_cb_t *vcb = &(mcl_cb->vtm_cb);/* vtm control block */ + + TRACELVL(5, (mcl_stdout, "-> mcl_vtm_initialize:\n")) + ASSERT(!mclcb->vtm_initialized); + memset(vcb, 0, sizeof(vtm_cb_t)); + vcb->max_ptm_size = VIRTUAL_TX_MAX_PHY_MEM_SIZE; + //vcb->cache_entry_size = mclcb->datagram_sz; /* fixed size! */ + vcb->cache_entry_size = mclcb->payload_size; /* fixed size! */ + if (!(pm_tab = (vtm_cache_entry_t*)calloc(mcl_vtm_cache_entry_nb, + sizeof(vtm_cache_entry_t))) || + !(pm_blk = (char*)malloc(mcl_vtm_cache_entry_nb * vcb->cache_entry_size))) + { + PRINT_ERR((mcl_stderr,"mcl_vtmem_initialize: ERROR: out of memory")) + mcl_exit(-1); + return; /* just to avoid a compiler warning! */ + } + for (i = 0, pm = pm_tab, off = 0; + i < (int)mcl_vtm_cache_entry_nb; + i++, pm++, off += vcb->cache_entry_size) { + pm->data = pm_blk + off; + } + vcb->cache_entry_nb = mcl_vtm_cache_entry_nb; + vcb->pmem_tab = pm_tab; + vcb->next_cache_index = 0; + + /* create temp file now in the tmp dir specified in mcl_tmp_dir_name */ +#ifdef WIN32 + strncpy(vcb->f_name, tempnam(mcl_tmp_dir_name, "mcl_vtm_"), + MAX_FILE_NAME_LEN); + if ((vcb->f_fd = open(vcb->f_name, _O_RDWR | O_CREAT | O_BINARY)) < 0) { + perror("mcl_vtmem_initialize: ERROR"); + PRINT_ERR((mcl_stderr,"mcl_vtmem_initialize: ERROR while creating tmp file \"%s\"", vcb->f_name)) + mcl_exit(-1); + return; /* just to avoid a compiler warning! */ + } +#else + strncat(vcb->f_name, mcl_tmp_dir_name, MAX_FILE_NAME_LEN); + strncat(vcb->f_name, "mcl_vtm_XXXXXX", MAX_FILE_NAME_LEN); + if ((vcb->f_fd = mkstemp(vcb->f_name)) < 0) { + perror("mcl_vtmem_initialize: ERROR"); + PRINT_ERR((mcl_stderr,"mcl_vtmem_initialize: ERROR while creating tmp file \"%s\"", vcb->f_name)) + mcl_exit(-1); + return; /* just to avoid a compiler warning! */ + } +#endif + mclcb->vtm_initialized = 1; + TRACELVL(5, (mcl_stdout, "<- mcl_vtm_initialize:\n")) +} + + +/* + * find seq consecutive slots in the phy memory cache, free them all, + * and return the first slot address. + */ +static vtm_cache_entry_t* +mcl_find_empty_slot (mcl_cb *mclcb, + int seq) /* # consecutive empty slots to find */ +{ + vtm_cache_entry_t *pm; + vtm_cache_entry_t *tmp_pm; + vtm_cb_t *vcb = &(mcl_cb->vtm_cb);/* vtm control block */ + int i; /* temporary counter */ + + TRACELVL(5, (mcl_stdout, "-> mcl_find_empty_slot: %d slots\n", seq)) + ASSERT(mcl_cb->vtm_initialized); + ASSERT(vcb->next_cache_index < vcb->cache_entry_nb); + if (vcb->next_cache_index + seq > vcb->cache_entry_nb) { + ASSERT(seq <= (int)vcb->cache_entry_nb); + vcb->next_cache_index = 0; + } + tmp_pm = pm = &(vcb->pmem_tab[vcb->next_cache_index]); + for (i = seq; i > 0; i--, tmp_pm++) { + ASSERT(tmp_pm); + ASSERT(tmp_pm->data); + if (tmp_pm->du) { + /* mark everything (du->data and pmem entry) unused */ + tmp_pm->du->data = NULL; + tmp_pm->du = NULL; + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_find_empty_slot: index=%d\n", vcb->next_cache_index)) + /* for next time */ + vcb->next_cache_index += seq; + vcb->next_cache_index %= vcb->cache_entry_nb; + return(pm); +} + + +#ifdef NEVERDEF +/* + * returns the offset within the vtm file, < 0 if error + */ +static int +mcl_find_position_on_disk (mcl_cb *mclcb, + du_t *du) +{ + u_int off; /* total offset within vtm file */ + + ASSERT(mcl_cb->vtm_initialized); + /* then add du offset within adu */ + off = du->vtm_info.off; + TRACELVL(5, (mcl_stdout, " mcl_find_position_on_disk: off=%d\n", off)) + return off; +} +#endif + + +/* + * read a sequence of seq DUs from disk and mark that they are now in vtm cache + */ +static int +mcl_copy_from_disk (mcl_cb *mclcb, + du_t *du, + int from_fd, + int from_off, + vtm_cache_entry_t *to, + int seq) /* # consecutive empty slots to find */ +{ + int i; + int len; + vtm_cb_t *vcb = &(mcl_cb->vtm_cb); /* vtm control block */ + du_t *tmp_du; + vtm_cache_entry_t *tmp_to; + + TRACELVL(5, (mcl_stdout, "-> mcl_copy_from_disk: %d DUs\n", seq)) + ASSERT(mcl_cb->vtm_initialized); + ASSERT(seq > 0); + /* repositionning within file is absolutely required! */ + if (lseek(from_fd, from_off, SEEK_SET) < 0) { + PRINT_ERR((mcl_stderr, "mcl_copy_from_disk: ERROR, lseek (fd=%d, off=%d) failed\n", + from_fd, from_off)) + perror("mcl_copy_from_disk: ERROR: lseek failed"); + mcl_exit(-1); + } + if ((len = read(from_fd, to->data, vcb->cache_entry_size * seq)) <= 0) { + PRINT_ERR((mcl_stderr,"mcl_copy_from_disk: ERROR, read returned %d\n", + len)) + perror("mcl_copy_from_disk: ERROR: read failed"); + /* + *PRINT_ERR((mcl_stderr,"ses_id=%d, fd=%d, data=x%x, size=%d\n", + *mclcb->id, from_fd, (int)to->data, vcb->cache_entry_size * seq)) + */ + mcl_exit(-1); + } + for (i = seq, tmp_du = du, tmp_to = to; i > 0; i--, tmp_du++, tmp_to++) { + ASSERT(tmp_du); + ASSERT(tmp_to->du == NULL); + if (tmp_du->data) { + vtm_cache_entry_t *cache_entry; + /* + * du data can already be in cache, eg. if sent + * recently on another layer + */ + TRACE((mcl_stderr, "mcl_copy_from_disk: WARNING, du->data already in cache, index=%d\n", i)) + /* + * remove from previous cache entry + */ + cache_entry = mcl_find_du_in_vtm_cache(mcl_cb, tmp_du); + cache_entry->du = NULL; + } + tmp_to->du = tmp_du; + tmp_du->data = tmp_to->data; + } + TRACELVL(5, (mcl_stdout, "<- mcl_copy_from_disk: %d copied\n", len)) + return 0; +} + + +/* + * linear search in the cache table + * not efficient but this function should be used only very occasionnaly! + */ +static vtm_cache_entry_t* +mcl_find_du_in_vtm_cache (mcl_cb *mclcb, + du_t *du) +{ + vtm_cb_t *vcb = &(mcl_cb->vtm_cb); /* vtm control block */ + vtm_cache_entry_t *pm; /* tmp var */ + int i; + + TRACELVL(5, (mcl_stdout, "-> mcl_find_du_in_vtm_cache:\n")) + for (i = 0, pm = vcb->pmem_tab; i < (int)mcl_vtm_cache_entry_nb; i++, pm++) { + if (pm->du == du) { + TRACELVL(5, (mcl_stdout, "<- mcl_find_du_in_vtm_cache: found\n")) + return pm; + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_find_du_in_vtm_cache: not in cache\n")) + return NULL; +} + + +#endif /* VIRTUAL_TX_MEM */ + diff --git a/src/alc/mcl_vtmem.h b/src/alc/mcl_vtmem.h new file mode 100644 index 0000000..7fb7d7d --- /dev/null +++ b/src/alc/mcl_vtmem.h @@ -0,0 +1,93 @@ +/* $Id: mcl_vtmem.h,v 1.3 2005/01/11 13:12:37 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * "virtual transmit memory service" (vtm) + */ + +#ifndef MCL_VTMEM_H /* { */ +#define MCL_VTMEM_H + +#ifdef VIRTUAL_TX_MEM + +/* + * adu/vtm or du/vtm correspondance + * stored in the adu_t and du_t structs + */ +typedef struct vtm_info { + char in_vtm; /* flag: 1 if off valid (ie. in vtm), */ + /* 0 otherwise (ie. in ptm) */ + char du_in_seq_in_txtab; /* remaining # DU in sequence in */ + /* txtab including this one */ + /* only meaningfull for a du_t struct */ + u_int off; /* adu or du offset within vtm file */ +} vtm_info_t; + + +/* + * describes each physical memory cache entry. + * managed as a single table of vtm_cache_entry_t structs in practice. + * the data pointer of the first entry gives the base address of the whole + * memory block as returned by malloc. + */ +typedef struct { + char *data; /* data block of this entry */ + struct du *du; /* owner of this entry */ +} vtm_cache_entry_t; + + +/* + * vtmem control block + */ +typedef struct { + /* description of the disk file */ + /* data of all ADUs is stored in this file (name/fd) */ + char f_name[MAX_FILE_NAME_LEN]; + int f_fd; + int f_len; /* current vtm file len */ + /* physical transmit memory area info */ + u_int max_ptm_size; /* max size in mem before using vtm */ + u_int ptm_size; /* total physical memory allocated */ + /* description of physical memory cache entries */ + u_int cache_entry_nb; /* actual nb of phy mem entries */ + u_int cache_entry_size;/* actual size of each pmem entry */ + vtm_cache_entry_t *pmem_tab; /* first phys mem entry in tab */ + /* physical memory entry management */ + u_int next_cache_index; /* next entry to use on pmem-fault */ +} vtm_cb_t; + + +/* + * public variables + */ +extern u_int vtm_cache_entry_nb; /* total number of entries in pmem */ + + +/* + * usefull macros + */ +#define mcl_is_adu_in_ptm(adu) ((adu)->vtm_info.in_vtm == 0 ? 1 : 0) +#define mcl_is_du_in_ptm(du) ((du)->vtm_info.in_vtm == 0 ? 1 : 0) + + +#endif /* VIRTUAL_TX_MEM */ + +#endif /* } MCL_VTMEM_H */ diff --git a/src/common/mcl_addr.cpp b/src/common/mcl_addr.cpp new file mode 100644 index 0000000..8c73da0 --- /dev/null +++ b/src/common/mcl_addr.cpp @@ -0,0 +1,523 @@ +/* $Id: mcl_addr.cpp,v 1.18 2005/05/24 15:43:22 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef ALC +#include "../alc/mcl_includes.h" + +#elif defined(NORM) + +#include "../norm/mcl_includes.h" +#endif // RM_PROTOCOL + + +mcl_addr::mcl_addr() +{ + /* + * Clear the address structure and set an IPv4 address family. + */ + memset(&(this->inet_address), 0, sizeof(this->inet_address)); + this->inet_address.sin.sin_family = AF_INET; + this->is_multicast = false; + this->is_inet6 = false; +} + + +mcl_addr::mcl_addr(bool is_ipv4) +{ + /* + * Clear the address structure and set the address family. + */ + memset(&(this->inet_address), 0, sizeof(this->inet_address)); + if (is_ipv4) { + this->inet_address.sin.sin_family = AF_INET; + this->is_multicast = false; + this->is_inet6 = false; + } +#ifdef INET6 + else { + this->inet_address.sin6.sin6_family = AF_INET6; + this->is_multicast = false; + this->is_inet6 = true; + } +#endif /* INET6 */ +} + + +mcl_addr::mcl_addr(const mcl_addr& address) +{ + /* + * Copy the address structure. + */ +#ifdef INET6 + if (address.is_ipv6_addr()) + this->inet_address.sin6 = address.inet_address.sin6; + else +#endif /* INET6 */ + this->inet_address.sin = address.inet_address.sin; + this->is_multicast = address.is_multicast; + this->is_inet6 = address.is_inet6; +} + + +mcl_addr& +mcl_addr::operator=(const mcl_addr& address) +{ + if (&address == NULL) return (*this); + else if (this != &address) { + /* Copy the address structure */ +#ifdef INET6 + if (address.is_ipv6_addr()) + this->inet_address.sin6 = + address.inet_address.sin6; + else +#endif /* INET6 */ + this->inet_address.sin = + address.inet_address.sin; + this->is_multicast = address.is_multicast; + this->is_inet6 = address.is_inet6; + } + return(*this); +} + + +mcl_addr::~mcl_addr() +{ + /* + * Do nothing. + */ +} + + +/****** SET FUNCTIONS *************************************************/ + +void +mcl_addr::reset() +{ + /* + * Clear the address structure and set the address family. + */ + memset(&(this->inet_address), 0, sizeof(this->inet_address)); + this->inet_address.sin.sin_family = AF_INET; + this->is_multicast = false; + this->is_inet6 = false; +} + + +void +mcl_addr::set_port(UINT16 port) +{ + /* + * Store the port. + * NB: the sin_port field is at the same place in sockaddr_in and + * sockaddr_in6 structures. No need to differentiate... + */ + this->inet_address.sin.sin_port = htons(port); +} + + +void +mcl_addr::set_any_port() +{ + /* + * Store the port number 0. + * NB: the sin_port field is at the same place in sockaddr_in and + * sockaddr_in6 structures. No need to differentiate... + */ + this->inet_address.sin.sin_port = htons(0); +} + + +void +mcl_addr::set_addr(UINT32 address) +{ + /* + * Store the address. Limited to IPv4. + */ +#ifdef INET6 + if (this->is_ipv6_addr()) { + PRINT_ERR((mcl_stderr, + "mcl_addr::set_addr: ERROR, IPv4 function called for IPv6 addr.\n")) + mcl_exit(-1); + } +#endif /* INET6 */ + this->inet_address.sin.sin_addr.s_addr = htonl(address); + if ((ntohl(this->inet_address.sin.sin_addr.s_addr) >> 24) >= 224) { + this->is_multicast = true; + } else { + this->is_multicast = false; + } +} + + +#ifdef INET6 +void +mcl_addr::set_addr(struct in6_addr *address) +{ + /* + * Store the address. Limited to IPv6. + */ + if (this->is_ipv6_addr() == false) { + PRINT_ERR((mcl_stderr, + "mcl_addr::set_addr: ERROR, IPv6 function called for IPv4 addr.\n")) + mcl_exit(-1); + } + memcpy((void*)(&(this->inet_address.sin6.sin6_addr)), (void*)address, + sizeof(struct in6_addr)); + if (IN6_IS_ADDR_MULTICAST(address)) { + this->is_multicast = true; + } else { + this->is_multicast = false; + } +} +#endif /* INET6 */ + + +void +mcl_addr::set_any_addr() +{ + /* + * Store the address IN(6)ADDR_ANY. + */ +#ifdef INET6 + if (this->is_ipv6_addr()) { + memcpy(&(this->inet_address.sin6.sin6_addr), &(in6addr_any), + sizeof(struct in6_addr)); + } else +#endif /* INET6 */ + { + this->inet_address.sin.sin_addr.s_addr = htonl(INADDR_ANY); + } + this->is_multicast = false; +} + + +/** + * Set the entire IPv4 or IPv6 address struct at one time. + */ +mcl_error_status +mcl_addr::set_addr_struct (const struct sockaddr *address) +{ + switch(address->sa_family) { + case AF_INET: + this->set_addr_struct((struct sockaddr_in*)address); + return MCL_OK; +#ifdef INET6 + case AF_INET6: + this->set_addr_struct((struct sockaddr_in6*)address); + return MCL_OK; +#endif /* INET6 */ + default: + PRINT_ERR((mcl_stderr, + "mcl_addr::set_addr_struct: ERROR, unsupported address family %d\n", + address->sa_family)) + return MCL_ERROR; + } +} + + +void +mcl_addr::set_addr_struct(const struct sockaddr_in *address) +{ + /* + * Get the address structure from address. + * Do this safely, copying only the required information. + */ + this->inet_address.sin.sin_port = address->sin_port; + this->inet_address.sin.sin_addr.s_addr = address->sin_addr.s_addr; + this->inet_address.sin.sin_family = AF_INET; + if ((ntohl(this->inet_address.sin.sin_addr.s_addr) >> 24) >= 224) { + this->is_multicast = true; + } else { + this->is_multicast = false; + } + this->is_inet6 = false; +} + + +#ifdef INET6 +void +mcl_addr::set_addr_struct(const struct sockaddr_in6 *address) +{ + /* + * Get the address structure from address. + * Do this safely, copying only the required information. + */ + this->inet_address.sin6.sin6_port = address->sin6_port; + this->inet_address.sin6.sin6_flowinfo = address->sin6_flowinfo; + memcpy(&(this->inet_address.sin6.sin6_addr), &(address->sin6_addr), + sizeof(struct in6_addr)); + this->inet_address.sin6.sin6_scope_id = address->sin6_scope_id; + this->inet_address.sin6.sin6_family = AF_INET6; + if (IN6_IS_ADDR_MULTICAST(&(address->sin6_addr))) { + this->is_multicast = true; + } else { + this->is_multicast = false; + } + this->is_inet6 = true; +} +#endif /* INET6 */ + + +void +mcl_addr::incr_addr (INT32 incr) +{ + if (incr == 0) { + return; + } +#ifdef INET6 + if (this->is_ipv6_addr()) { +#ifdef WIN32 + struct in6_addr in6; // temp new IPv6 addr + INT32 val; // temp byte value + + in6 = this->inet_address.sin6.sin6_addr; + // low byte in address is the 16th... + // the following method assumes no overflow... + val = ntohs(in6.s6_words[7]); + val += incr; + in6.s6_words[7] = htons(val); + this->set_addr(&in6); +#else /* Unix */ +#ifdef SOLARIS /* not defined on Solaris for user level code */ +#define s6_addr32 _S6_un._S6_u32 +#elif defined(FREEBSD) /* not defined on FreeBSD for user level code */ +#define s6_addr32 __u6_addr.__u6_addr32 +#endif + struct in6_addr in6; // temp new IPv6 addr + INT32 val; // temp byte value + + in6 = this->inet_address.sin6.sin6_addr; + // low byte in address is the 16th... + // the following method assumes no overflow... + val = ntohl(in6.s6_addr32[3]); + val += incr; + in6.s6_addr32[3] = htonl(val); + this->set_addr(&in6); +#endif /* OS */ + } else +#endif /* INET6 */ + this->set_addr(this->get_addr() + incr); +} + + +void +mcl_addr::incr_port (INT32 incr) +{ + this->set_port(this->get_port() + incr); +} + + +/****** GET FUNCTIONS *************************************************/ + +UINT16 +mcl_addr::get_port() const +{ + /* + * Return the port. + * NB: the sin_port field is at the same place in sockaddr_in and + * sockaddr_in6 structures. No need to differentiate... + */ + return(ntohs(this->inet_address.sin.sin_port)); +} + + +char* +mcl_addr::get_port_string () const +{ + static char str[32]; + + sprintf(str, "%d", this->get_port()); + return str; +} + + +UINT32 +mcl_addr::get_addr() const +{ + /* + * Return the address. + */ +#ifdef INET6 + if (this->is_ipv6_addr()) { + PRINT_ERR((mcl_stderr, + "mcl_addr::get_addr: ERROR, IPv4 function called for IPv6 addr.\n")) + mcl_exit(-1); + } +#endif /* INET6 */ + return(ntohl(this->inet_address.sin.sin_addr.s_addr)); +} + + +void +mcl_addr::get_addr_struct(struct sockaddr_in *address) const +{ + /* + * Set address to the address structure. + */ +#ifdef INET6 + if (this->is_ipv6_addr()) { + PRINT_ERR((mcl_stderr, + "mcl_addr::get_addr_struct: ERROR, IPv4 function called for IPv6 addr.\n")) + mcl_exit(-1); + } +#endif /* INET6 */ + *address = this->inet_address.sin; +} + +#ifdef INET6 +void +mcl_addr::get_addr_struct(struct sockaddr_in6 *address) const +{ + /* + * Set address to the address structure. + */ +#ifdef INET6 + if (this->is_ipv6_addr() == false) { + PRINT_ERR((mcl_stderr, + "mcl_addr::get_addr_struct: ERROR, IPv6 function called for IPv4 addr.\n")) + mcl_exit(-1); + } +#endif /* INET6 */ + + memcpy(address, &(this->inet_address.sin6), + sizeof(struct sockaddr_in6)); +} +#endif /* INET6 */ + + +char* +mcl_addr::get_addr_string() const +{ + /* Warning: inet_ntoa is not re-entrant! */ +#ifdef INET6 +#ifdef WIN32 + if (this->is_ipv6_addr()) { + static char str[INET6_ADDRSTRLEN]; + DWORD len = INET6_ADDRSTRLEN; + struct sockaddr_in6 *sa6; + INT32 port; + + /* we just want the address without port... + * temporarly set the port to 0 */ + sa6 = (struct sockaddr_in6*)&(this->inet_address.sin6); + int port = sa6->sin6_port; + sa6->sin6_port = htons(0); + if (WSAAddressToString((struct sockaddr*) &(this->inet_address.sin6), + sizeof(this->inet_address.sin6), NULL, str, &len) != 0) { + PRINT_ERR((mcl_stderr, + "mcl_addr::get_addr_string: ERROR, WSAStringToAddress failed: %i\n", + WSAGetLastError())) + } + /* set the port to its initial value */ + sa6->sin6_port = port; + return(str); + } +#else /* UNIX */ + static char str[INET6_ADDRSTRLEN]; + if (this->is_ipv6_addr()) { + if (inet_ntop(AF_INET6, &(this->inet_address.sin6.sin6_addr), + str, sizeof(str)) == NULL) { + return((char*)"mcl_addr::get_addr_string: ERROR, inet_ntop failed\n"); + } else { + return(str); + } + } +#endif /* OS */ + else +#endif /* INET6 */ + return(inet_ntoa(this->inet_address.sin.sin_addr)); +} + + +#if 0 +bool +mcl_addr::is_multicast_addr() const +{ + /* + * Check if the address is a multicast address. + */ + if ((ntohl(this->inet_address.sin_addr.s_addr) >> 24) >= 224) { + return(true); + } else { + return(false); + } +} +#endif + + +bool +mcl_addr::is_equal(const mcl_addr& address) const +{ + /* + * Check if the specified address is the "same". + */ +#ifdef INET6 + if (address.is_ipv6_addr()) { + if ((this->inet_address.sin6.sin6_family == address.inet_address.sin6.sin6_family)&& + (this->inet_address.sin6.sin6_port == address.inet_address.sin6.sin6_port) && + memcmp(&(this->inet_address.sin6.sin6_addr), + &(address.inet_address.sin6.sin6_addr), sizeof(in6_addr)) == 0) { + return(true); + } else { + return(false); + } + } else +#endif /* INET6 */ + { + if ((this->inet_address.sin.sin_family == address.inet_address.sin.sin_family)&& + (this->inet_address.sin.sin_port == address.inet_address.sin.sin_port) && + (this->inet_address.sin.sin_addr.s_addr == address.inet_address.sin.sin_addr.s_addr)) { + return(true); + } else { + return(false); + } + } +} + + +bool +mcl_addr::addr_is_equal(const mcl_addr& address) const +{ + /* + * Check if the specified address is the "same". + * Do not consider the port, only the addr. + */ +#ifdef INET6 + if (address.is_ipv6_addr()) { + if ((this->inet_address.sin6.sin6_family == address.inet_address.sin6.sin6_family)&& + memcmp(&(this->inet_address.sin6.sin6_addr), + &(address.inet_address.sin6.sin6_addr), sizeof(in6_addr)) == 0) { + return(true); + } else { + return(false); + } + } else +#endif /* INET6 */ + { + if ((this->inet_address.sin.sin_family == address.inet_address.sin.sin_family)&& + (this->inet_address.sin.sin_addr.s_addr == address.inet_address.sin.sin_addr.s_addr)) { + return(true); + } else { + return(false); + } + } +} + diff --git a/src/common/mcl_addr.h b/src/common/mcl_addr.h new file mode 100644 index 0000000..ba5f5aa --- /dev/null +++ b/src/common/mcl_addr.h @@ -0,0 +1,323 @@ +/* $Id: mcl_addr.h,v 1.6 2004/06/02 13:37:33 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_ADDR_H +#define MCL_ADDR_H + + +/** + * Class defining an IP address. + * Supports both IPv4 and IPv6. + */ +class mcl_addr { + +public: + /** + * Default constructor. + * By default creates a null AF_INET (i.e. IPv4) object. + */ + mcl_addr (); + + /** + * Default constructor. + * By default creates a null AF_INET (i.e. IPv4) object. + * @param is_ipv4 true if object is IPv4, false if object is IPv6 + */ + mcl_addr (bool is_ipv4); + + /** + * Copy constructor. + * @param address The address object to copy. + */ + mcl_addr (const mcl_addr & address); + + /** + * The destructor. + */ + ~mcl_addr (); + + /** + * The operator=. + * @param address The address object to copy. + * @return A reference to this object. + */ + mcl_addr & operator=(const mcl_addr & address); + + /** + * Manual reset of an address. + * This function resets all fields of the address. + * Usefull when the default constructor cannot be called. + * By default creates a null AF_INET struct. + */ + void reset (void); + + + /****** SET FUNCTIONS *************************************************/ + + /** + * Set the port number. + * @param port New port number in host byte order. + */ + void set_port (UINT16 port); + + /** + * Set the port number to "any". + */ + void set_any_port (); + + /** + * Set an IPv4 address. + * Restricted to IPv4 addresses. + * @param address New address (INT32) in host byte order. + */ + void set_addr (UINT32 address); + +#ifdef INET6 + /** + * Set an IPv6 address. + * Restricted to IPv6 addresses. + * @param address New address in host byte order. + */ + void set_addr (struct in6_addr *address); +#endif /* INET6 */ + + /** + * Set the address to "any". + */ + void set_any_addr (); + + /** + * Set the entire IPv4 or IPv6 address struct at one time. + * The sockaddr structure must be fully initialized, including + * the address family. + * @param address New sockaddr structure. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_addr_struct (const struct sockaddr *address); + + /** + * Set the entire IPv4 address struct at one time. + * @param address New IPv4 sockaddr_in structure. + */ + void set_addr_struct (const struct sockaddr_in *address); + +#ifdef INET6 + /** + * Set the entire IPv6 address struct at one time. + * @param address New IPv6 sockaddr_in6 structure. + */ + void set_addr_struct (const struct sockaddr_in6 *address); +#endif /* INET6 */ + + /** + * Increment the IPv4 or IPv6 address value. + * @param incr value to add. + */ + void incr_addr (INT32 incr); + + /** + * Increment the port value. + * @param incr value to add. + */ + void incr_port (INT32 incr); + + + /****** GET FUNCTIONS *************************************************/ + + /** + * Return the address family (AF_INET or AF_INET6). + * @return Address familly. + */ + INT32 get_addr_family () const; + + /** + * Return the address port number. + * @return Address port number in host byte order. + */ + UINT16 get_port () const; + + /** + * Return the address port number as a string. + * Warning: get_port_string is not re-entrant (static string)! + * @return Address port number as a string. + */ + char* get_port_string () const; + + /** + * Returns the sockaddr_in/sockaddr_in6 length. + * @reuturn Length in bytes of the internal sockaddr_in + * or sockaddr_in6 structure. + */ + INT32 get_addr_struct_len (void) const; + + /** + * Return the IPv4 address as a UINT32. + * @return Address in host byte order. + */ + UINT32 get_addr () const; + + /** + * Get the entire IPv4 address at one time. + * @param address Pointer to a sockaddr_in structure where + * the address will be placed in network byte + * order. + */ + void get_addr_struct (struct sockaddr_in *address) const; + +#ifdef INET6 + /** + * Get the entire IPv6 address at one time. + * @param address Pointer to a sockaddr_in6 structure where + * the address will be placed in network byte + * order. + */ + void get_addr_struct (struct sockaddr_in6 *address) const; +#endif /* INET6 */ + + /** + * Return the internal sockaddr buffer address. + * Works for both IPv4 and IPv6 addresses. + * @return address of internal sockaddr buffer. + */ + struct sockaddr* get_internal_struct_addr (void); + + /** + * Return the address as a string in dot-decimal format. + * Warning: inet_ntoa is not re-entrant, and get_addr_string isn't too! + * @return Temporary character buffer containing + * the string. This buffer is overwritten by + * subsequent calls to this method. + */ + char* get_addr_string () const; + + + /****** TEST FUNCTIONS ************************************************/ + + /** + * Checks if the address is a multicast address. + * @return TRUE if this is a multicast address, + * FALSE otherwise. + */ + bool is_multicast_addr () const; + + /** + * Checks if the address is an IPv4 address. + * @return TRUE if this is an IPv6 address, + * FALSE otherwise. + */ + bool is_ipv4_addr () const; + +#ifdef INET6 + /** + * Checks if the address is an IPv6 address. + * @return TRUE if this is an IPv6 address, + * FALSE otherwise. + */ + bool is_ipv6_addr () const; +#endif /* INET6 */ + + /** + * Checks if the specified object is the "same" as this object. + * This function compares all fields of the address object. + * @param address The address to compare against. + * @return TRUE if the address is the "same" as + * this object, FALSE otherwise. + */ + bool is_equal (const mcl_addr & address) const; + + /** + * Checks if the IP address of the specified object is the "same" + * as this object. + * It does not consider the port info, only the IP address. + * @param address The address to compare against. + * @return TRUE if the address is the "same" as this + * object, FALSE otherwise. + */ + bool addr_is_equal (const mcl_addr & address) const; + + + /****** PRIVATE *******************************************************/ +private: + + /** + * The internet address structure in network byte order. + */ + union { + struct sockaddr_in sin; +#ifdef INET6 + struct sockaddr_in6 sin6; +#endif /* INET6 */ + } inet_address; + + bool is_multicast; + bool is_inet6; /* true if AF_INET6, false if AF_INET */ +}; + + +//---------------------------------------------------------------------------- +// Inlines for all classes follow +//---------------------------------------------------------------------------- + +inline INT32 +mcl_addr::get_addr_family () const +{ + return((this->is_inet6 == true) ? AF_INET6 : AF_INET); +} + +inline bool +mcl_addr::is_multicast_addr() const +{ + return (this->is_multicast); +} + +inline INT32 +mcl_addr::get_addr_struct_len (void) const +{ +#ifdef INET6 + if (this->is_inet6) + return (sizeof(struct sockaddr_in6)); + else +#endif + return (sizeof(struct sockaddr_in)); +} + +inline struct sockaddr* +mcl_addr::get_internal_struct_addr () +{ + return ((struct sockaddr*) &(this->inet_address)); +} + +inline bool +mcl_addr::is_ipv4_addr () const +{ + return (!(this->is_inet6)); +} + +#ifdef INET6 +inline bool +mcl_addr::is_ipv6_addr () const +{ + return (this->is_inet6); +} +#endif /* INET6 */ + +#endif // MCL_ADDR_H + diff --git a/src/common/mcl_blocking_struct.cpp b/src/common/mcl_blocking_struct.cpp new file mode 100644 index 0000000..f04b345 --- /dev/null +++ b/src/common/mcl_blocking_struct.cpp @@ -0,0 +1,61 @@ +/* $Id: mcl_blocking_struct.cpp,v 1.2 2004/08/06 07:16:26 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#ifdef ALC +#include "../alc/mcl_includes.h" + +#elif defined(NORM) + +#include "../norm/mcl_includes.h" +#endif // ALC|NORM + + +/** + * Compute source block structure. + * => See header file for more informations. + */ +void +mcl_compute_blocking_struct (UINT32 B, + UINT32 L, + UINT32 E, + mcl_blocking_struct_t *bs) +{ + UINT32 T; /* number of source symbols in the object */ + double A; /* average length of a source block in number of symbols */ + double A_fraction; + + T = (UINT32)ceil((double)L / (double)E); + bs->block_nb = (INT32)ceil((double)T / (double)B); + A = (double)T/(double)bs->block_nb; /* average size of a block; non integer */ + bs->A_large = (UINT32)ceil((double)A); + bs->A_small = (UINT32)floor((double)A); + ASSERT(bs->A_large <= B); + A_fraction = A - bs->A_small; + bs->I = double_to_closest_int(A_fraction * (double)bs->block_nb); +#if 0 + PRINT_OUT((mcl_stdout, + " mcl_compute_blocking_struct: B=%d, L=%d, E=%d\n\t\tblock_nb=%d, I=%d, A_large=%d, A_small=%d\n", + B, L, E, bs->block_nb, bs->I, bs->A_large, bs->A_small)) +#endif +} + + diff --git a/src/common/mcl_blocking_struct.h b/src/common/mcl_blocking_struct.h new file mode 100644 index 0000000..c364beb --- /dev/null +++ b/src/common/mcl_blocking_struct.h @@ -0,0 +1,55 @@ +/* $Id: mcl_blocking_struct.h,v 1.2 2004/02/09 11:29:53 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/** + * Blocking structure. Defines the number and size of each block, as + * defined in the FLUTE document. + */ +typedef struct mcl_blocking_struct { + UINT32 block_nb;// number of source blocks into which the object + // is partitioned (N parameter of the FLUTE doc). + UINT32 I; // number of source blocks of length A_large symbols + // (pointer). These blocks are the first I blocks. + // The remaining N-I blocks are of size A_small. + UINT32 A_large;// length in source symbols of the first I large // source blocks. + UINT32 A_small;// length in source symbols of the remaining N-I + // smaller blocks. +} mcl_blocking_struct_t; + + +/** + * Compute source block structure. + * Follows closely the algorithm specified in FLUTE. + * @param B (IN) maximum number of source symbols per source block. + * @param L (IN) transfer length (i.e. object size) in bytes. + * @param E (IN) encoding symbol length in bytes. + * @param bs (OUT) blocking structure, containing the N, I, A_large + * and A_small values. This structure must be allocated/freed + * by the caller. + */ +void mcl_compute_blocking_struct ( + UINT32 B, + UINT32 L, + UINT32 E, + mcl_blocking_struct_t *bs); + + diff --git a/src/common/mcl_debug.cpp b/src/common/mcl_debug.cpp new file mode 100644 index 0000000..1decfa7 --- /dev/null +++ b/src/common/mcl_debug.cpp @@ -0,0 +1,112 @@ +/* $Id: mcl_debug.cpp,v 1.9 2005/01/11 13:12:37 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef ALC +#include "../alc/mcl_includes.h" + +#elif defined(NORM) + +#include "../norm/mcl_includes.h" +extern void mcl_exit (int n); +#endif // ALC|NORM + +#ifdef DEBUG + +/* + * Called only when an ASSERT failes. Usefull to set up a breakpoint. + */ +void +mcl_assert (void) +{ + mcl_exit(-1); +} + + +/* + * Call it when you want to easily setup a breakpoint somewhere in code. + */ +void +mcl_break (void) +{ + return; +} + +#endif /* DEBUG */ + + +/** + * Dump a data buffer. + * @param len total length of the buffer + * @param to_dump number of UINT32 words to dump + */ +void +mcl_dump_buffer (char *buf, + int len, + int to_dump) /* number of u32 words to dump */ +{ + int i, j; + int *ptr; + +#ifndef min +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#endif + i = min(to_dump, (len >> 2)); + j = 0; + PRINT_OUT((mcl_stdout, "\tDUMP %d first bytes...\n\t", i * sizeof(int))) + for (ptr = (int*)buf; i > 0; i--, ptr++) { + /* convert to big endian format to be sure of byte order */ + PRINT_OUT((mcl_stdout, "%08lx ", htonl(*ptr))) + if (++j == 8) { + j = 0; + PRINT_OUT((mcl_stdout, "\n\t")) + } + } + PRINT_OUT((mcl_stdout, "\n")) +} + +/** + * Dump a data buffer containing ascii content. + * @param to_dump number of bytes to dump + */ +void +mcl_dump_ascii_buffer (char *buf, + int to_dump) /* number of bytes to dump */ +{ + int i, j; + char *ptr; + +#ifndef min +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#endif + i = to_dump; + j = 0; + PRINT_OUT((mcl_stdout, "\tDUMP %d first bytes...\n---START-----\n\t", i * sizeof(int))) + for (ptr = buf; i > 0; i--, ptr++) { + /* convert to big endian format to be sure of byte order */ + PRINT_OUT((mcl_stdout, "%c", *ptr)) + if (++j == 40) { + j = 0; + PRINT_OUT((mcl_stdout, "\n\t")) + } + } + PRINT_OUT((mcl_stdout, "\n---END-------\n")) +} + diff --git a/src/common/mcl_debug.h b/src/common/mcl_debug.h new file mode 100644 index 0000000..e8b498a --- /dev/null +++ b/src/common/mcl_debug.h @@ -0,0 +1,140 @@ +/* $Id: mcl_debug.h,v 1.6 2005/01/11 13:12:38 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/****** prototypes ******/ + +extern FILE *mcl_stdout; +extern FILE *mcl_stderr; + + +/** + * Dump a data buffer in hexa. + * @param len total length of the buffer + * @param to_dump number of UINT32 words to dump + */ +extern void mcl_dump_buffer (char *buf, int len, int to_dump); + +/** + * Dump a data buffer in ascii. + * @param len total length of the buffer + * @param to_dump number of UINT32 words to dump + */ +extern void mcl_dump_ascii_buffer (char *buf, int to_dump); + + +/****** general macros ******/ + +/* + * print to stdout + */ +#define PRINT_OUT(a) { \ + fprintf a; \ + fflush(mcl_stdout); \ + } + +/* + * print to stderr + */ +#define PRINT_ERR(a) { \ + fprintf a; \ + fflush(mcl_stderr); \ + } + +/* + * Print according to level + */ +#ifdef ALC +#define PRINT_LVL(l, a) if (mclcb->verbose >= (l)) { \ + fprintf a; \ + fflush(mcl_stdout); \ + } +#else +#define PRINT_LVL(l, a) if (mclcb->get_verbosity() >= (l)) { \ + fprintf a; \ + fflush(mcl_stdout); \ + } +#endif + +/* + * Trace only in debug mode according to level + */ +#ifdef DEBUG +#define TRACE(a) { \ + fprintf a; \ + fflush(mcl_stdout); \ + } + +#define TRACELVL(l, a) if (mclcb->get_verbosity() >= (l)) { \ + fprintf a; \ + fflush(mcl_stdout); \ + } + +#else /* DEBUG */ +#define TRACE(a) ; /* empty instruction is less risky */ +#define TRACELVL(lvl, a) ; /* empty instruction is less risky */ +#endif /* DEBUG */ + +#if 0 +/* + * Close everything and exit. + */ +#define EXIT(c, n) { \ + if (c) \ + kill(getppid(), SIGUSR2); \ + mcl_exit(n); \ + } +#endif + +/* + * Check that an assertion is true. + */ +#ifdef ASSERT /* in case it was already defined, erase it... */ +#undef ASSERT +#endif + +#ifdef DEBUG +/* More convenient with a function since we can breakpoint it! */ +extern void mcl_assert (void); +#define ASSERT(c) { \ + if (!(c)) { \ + fprintf(stderr, "ASSERT [%s:%d] failed\n", \ + __FILE__, __LINE__); \ + fflush(stderr); \ + mcl_assert(); \ + } \ + } +#else /* DEBUG */ +#define ASSERT(c) +#endif /* DEBUG */ + + +/****** Other debug functions ******/ + +#ifdef ALC +#ifdef DEBUG +#define PRINTDULIST(tl) PrintDUList(tl) +#else /* DEBUG */ +#define PRINTDULIST(tl) +#endif /* DEBUG */ +#endif /* ALC */ + +#define MAGIC_VER 0XAB /* magic char number for pkt header debug */ + diff --git a/src/common/mcl_defines.h b/src/common/mcl_defines.h new file mode 100644 index 0000000..43adc66 --- /dev/null +++ b/src/common/mcl_defines.h @@ -0,0 +1,61 @@ +/* $Id: mcl_defines.h,v 1.1 2004/06/07 09:44:50 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_DEFINES_H /* { */ +#define MCL_DEFINES_H + + +/****** general purpose enumerations ******************************************/ + +/** + * Error status returned by functions + */ +enum mcl_error_status { + MCL_OK = 0, + MCL_ERROR = 1 +}; + + +/****** general purpose macros ************************************************/ + +#ifndef min +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#endif + +#ifndef max +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#endif + + +/* WARNING: works only with integers */ +#define is_odd(v) ( ((v) & 1) ? 1 : 0) + + +/****** constants: do not edit ************************************************/ + +/* + * max length of char strings / paht+file names + */ +#define MAX_NAME_LEN 64 +#define MAX_FILE_NAME_LEN 256 + + +#endif /* } MCL_DEFINES_H */ diff --git a/src/common/mcl_file_io.cpp b/src/common/mcl_file_io.cpp new file mode 100644 index 0000000..14573c9 --- /dev/null +++ b/src/common/mcl_file_io.cpp @@ -0,0 +1,85 @@ +/* $Id: mcl_file_io.cpp,v 1.4 2005/03/23 14:05:04 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef ALC +#include "../alc/mcl_includes.h" + +#elif defined(NORM) + +#include "../norm/mcl_includes.h" +#endif // RM_PROTOCOL + + +int +mcl_file_open (const char *filename, + int flags, + mode_t mode) +{ + int err; + + if ((err = open(filename, flags, mode)) < 0) { + perror("mcl_file_open: ERROR"); + } + return err; +} + +int +mcl_file_close (int fd) +{ + int err; + if ((err = close(fd)) < 0) { + perror("mcl_file_close: ERROR"); + } + return err; +} + +/** + * Reposition read/write file offset. + */ +INT64 +mcl_file_lseek (int fd, + INT64 offset) +{ + return(lseek(fd, (off_t)offset, SEEK_SET)); +} + +/** + * Read from a file descriptor. + */ +INT64 +mcl_file_read (int fd, + void *buf, + INT64 count) +{ + return(read(fd, buf, (size_t)count)); +} + +/** + * Write to a file descriptor. + */ +INT64 +mcl_file_write (int fd, + const void *buf, + INT64 count) +{ + return(write(fd, buf, (size_t)count)); +} + diff --git a/src/common/mcl_file_io.h b/src/common/mcl_file_io.h new file mode 100644 index 0000000..e725f70 --- /dev/null +++ b/src/common/mcl_file_io.h @@ -0,0 +1,95 @@ +/* $Id: mcl_file_io.h,v 1.3 2005/01/11 13:12:38 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_FILE_IO_H +#define MCL_FILE_IO_H + + +/** + * Open the file whose name is provided, and associates a file descriptor + * to it. + * This function is clooser in spirit to open(2) (that returns a filedescr) + * than to fopen(2) (that returns a stream). If a flag argument is provided, + * note that other arguments (e.g. O_LARGEFILE) may be automatically added. + * @param filename file name + * @param flags one of O_RDONLY, O_WRONLY or O_RDWR, and other + * possible flags, as specified in open(2) + * @param mode specifies the permissions to use in case a new file + * is created, as specified in open(2) + * @return mcl_fopen returns the new file descriptor, or + * -1 if an error occurred. + */ +extern int mcl_file_open (const char *filename, int flags, mode_t mode); + +/** + * Close a file descriptor, so that it no longer refers to any file. + * This function is clooser in spirit to close(2) (that takes a filedescr) + * than to fclose(3) (that takes a stream). + * @param fd file descriptor + * @return return zero on success, or -1 if an error occurred. + */ +extern int mcl_file_close (int fd); + +/** + * Reposition read/write file offset. + * The lseek function repositions the offset of the file of desciptor fd + * to the argument offset. The offset is always considered from the begining + * of the file. + * @param fd + * @param offset + * @return + * Upon successful completion, lseek returns the resulting offset location + * as measured in bytes from the beginning of the file. Otherwise, a + * value of -1 is returned and errno is set to indicate the error. + */ +extern INT64 mcl_file_lseek (int fd, INT64 offset); + +/** + * Read from a file descriptor. + * Reads up to count bytes from the file referenced by the file + * descriptor fd to the buffer starting at buf. + * + * @param fd + * @param buf + * @param count + * @return + * On success, the number of bytes read is returned (zero indicates + * nothing was read). On error, -1 is returned and errno is set + * appropriately. + */ +extern INT64 mcl_file_read (int fd, void *buf, INT64 count); + +/** + * Write to a file descriptor. + * Writes up to count bytes to the file referenced by the file + * descriptor fd from the buffer starting at buf. + * + * @param fd + * @param buf + * @param count + * @return + * On success, the number of bytes written is returned (zero indicates + * nothing was written). On error, -1 is returned and errno is set + * appropriately. + */ +extern INT64 mcl_file_write(int fd, const void *buf, INT64 count); + +#endif /* MCL_FILE_IO_H */ diff --git a/src/common/mcl_itime.cpp b/src/common/mcl_itime.cpp new file mode 100644 index 0000000..4e0d982 --- /dev/null +++ b/src/common/mcl_itime.cpp @@ -0,0 +1,137 @@ +/* $Id: mcl_itime.cpp,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef ALC +#include "../alc/mcl_includes.h" + +#elif defined(NORM) + +#include "../norm/mcl_includes.h" +#endif // ALC|NORM + + +/****** mcl_itime functions ***************************************************/ + +/* + * See mcl_time.h for internal MCL time representation + */ + +#ifndef ITIME_FUNCTION_DEFINES + +mcl_itime_t +mcl_usec2it (int from) +{ + return((int)(from / 1000)); +} + + +int +mcl_it2usec (mcl_itime_t from) +{ + return(from * 1000); +} + + +float +mcl_it2sec (mcl_itime_t from) +{ + return((float)from * 0.001); +} + + +mcl_itime_t +mcl_itime_sub (mcl_itime_t val, + mcl_itime_t decr) +{ + return(val - decr); +} + + +mcl_itime_t +mcl_itime_add (mcl_itime_t val + mcl_itime_t incr) +{ + return(val + decr); +} + + +mcl_itime_t +mcl_tv2it (struct timeval tv) +{ + return(tv.tv_sec * 1000 + (long)((float)tv.tv_usec * 0.001)); +} + +#endif /* !ITIME_FUNCTION_DEFINES */ + + +/****** timeval functions *****************************************************/ + + +/* + * normalises a timeval struct + * time in usec = sec * 1000000 + usec + * normalised time is such that usec is in [0,999999] + */ +struct timeval +mcl_norm_tvtime(struct timeval val) +{ + while (val.tv_usec < 0) { + val.tv_usec += 1000000; + val.tv_sec--; + } + while (val.tv_usec >= 1000000) { + val.tv_usec -= 1000000; + val.tv_sec++; + } + return val; +} + + +/****** get time functions ****************************************************/ + + +static int time_initialized = 0; +static struct timeval tv0; /* initial timeval at initialization */ + + +mcl_itime_t +mcl_get_itime () +{ + return(mcl_tv2it(mcl_get_tvtime())); +} + + +struct timeval +mcl_get_tvtime () +{ + struct timeval tv; + + if (!time_initialized) { + time_initialized = 1; + mcl_gettimeofday(&tv0); + /*it0 = mcl_tv2it(tv0);*/ + } + mcl_gettimeofday(&tv); + tv.tv_sec -= tv0.tv_sec; + tv.tv_usec -= tv0.tv_usec; + return mcl_norm_tvtime(tv); +} + diff --git a/src/common/mcl_itime.h b/src/common/mcl_itime.h new file mode 100644 index 0000000..f3c2603 --- /dev/null +++ b/src/common/mcl_itime.h @@ -0,0 +1,55 @@ +/* $Id: mcl_itime.h,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * Internal MCL time representation is in milli-seconds (ms) + * Being stored in a signed 32 bit int, it will cycle after 596h31 + */ +typedef INT32 mcl_itime_t; + + +/* define for optimized time management functions */ +#define ITIME_FUNCTION_DEFINES + +#ifdef ITIME_FUNCTION_DEFINES + +#define mcl_usec2it(from) ((INT32)((from) / 1000)) +#define mcl_it2usec(from) ((from) * 1000) +#define mcl_it2sec(from) ((float)(from) * 0.001) +#define mcl_itime_sub(val,decr) ((val) - (decr)) +#define mcl_itime_add(val,incr) ((val) + (incr)); +#define mcl_tv2it(tv) ((tv).tv_sec * 1000 + (INT32)((float)(tv).tv_usec * 0.001)) + +#else + +extern mcl_itime_t mcl_usec2it (int from); +extern int mcl_it2usec (mcl_itime_t from); +extern float mcl_it2sec (mcl_itime_t from); +extern mcl_itime_t mcl_itime_sub (mcl_itime_t val, mcl_itime_t decr); +extern mcl_itime_t mcl_itime_add (mcl_itime_t val, mcl_itime_t incr); + +#endif /* !ITIME_FUNCTION_DEFINES */ + +extern mcl_itime_t mcl_get_itime (void); +extern struct timeval mcl_get_tvtime (void); + +extern struct timeval mcl_norm_tvtime(struct timeval val); + diff --git a/src/common/mcl_lib_api.h b/src/common/mcl_lib_api.h new file mode 100644 index 0000000..bdb74a6 --- /dev/null +++ b/src/common/mcl_lib_api.h @@ -0,0 +1,320 @@ +/* $Id: mcl_lib_api.h,v 1.14 2005/03/18 12:06:20 roca Exp $ */ +/* + * Copyright (c) 1999-2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_LIB_API_H +#define MCL_LIB_API_H + +#include "mcl_types.h" /* define portable data types */ + + +/* + * MCL API definition. + * This is the ONLY header file that must be included by all external + * applications! + * + * This common part of the MCL API includes a reliable multicast specific + * part, depending on whether ALC or NORM is used. + * This RM-specific part defines the various control parameters that can + * be set with mcl_ctl(). You should have a look at it if you build an + * application on top of MCL. + */ + + +/****** ALC or NORM Specific Part *********************************************/ + +/* + * library options set with the mcl_ctl() function are defined in these + * include files. + */ +#ifdef ALC +#include "../alc/mcl_lib_api_alc.h" +#elif defined NORM +#include "../norm/mcl_lib_api_norm.h" +#else +Error, either ALC or NORM should be defined when including this file according +to the reliable multicast protocol you want to use... +#endif + + +/****** Common Part ***********************************************************/ + +/** + * Open an MCL-ALC or MCL-NORM session. + * Wether it uses ALC or NORM as its reliable multicast protocol depends + * on the compilation parameters. The same application cannot concurrently + * have ALC and NORM sessions, they are mutually exclusive (this is a + * limitation of the current implementation!). + * + * @param mode defines the kind of session ("r", "w") + * @return returns to appli a unique identifier if ok, or < 0 in case of error + */ +extern INT32 mcl_open (const char *mode); + +/** + * Close the MCL session. + * + * @param id MCL session identifier + * @return returns 0 if ok, or < 0 in case of error + */ +extern INT32 mcl_close (INT32 id); + +extern INT32 mcl_abort (INT32 id); + +/** + * Get or set control parameters for the session. + * Follows the Unix ioctl() syscall interface. + * Warning: usually the tx and rx contexts are still not fully initialized! + * This is only done during the first call to mcl_send or mcl_recv... + * + * @param id MCL session identifier + * @param optname the option to set/get/change + * @param optvalue the associated value to set or to read. It is + * either a simple type (e.g. INT32) or a structure + * (e.g. struct sockaddr). This value can be either + * set in MCL or read from MCL's internals and + * returned to the appli. + * @param optlen the length in bytes of the associated value field + * @return returns 0 if ok, or < 0 in case of error + */ +extern INT32 mcl_ctl (INT32 id, INT32 optname, void *optvalue, + INT32 optlen); + +/** + * mcl_send data sending function. + * + * @param id MCL session identifier + * @param data data block; in MCL_OPT_REUSE_APPLI_TX_BUFFER mode, the + * data pointer must be the result of a standard + * malloc/calloc/realloc function call. + * @param len data block length in bytes + * @return number of bytes sent or -1 if error + */ +extern INT32 mcl_send (INT32 id, const void *data, INT32 len); + +/** + * mcl_sendto data sending function. + * + * @param id MCL session identifier + * @param data data block; in MCL_OPT_REUSE_APPLI_TX_BUFFER mode, the + * data pointer must be the result of a standard + * malloc/calloc/realloc function call. + * @param len data block length in bytes + * @param saddr destination sockaddr structure corresponding to an IPv4 + * or IPv6 address + * @param saddr_len sockaddr structure actual length (the sockaddr + struct is generic!) + * @return number of bytes sent or -1 if error + */ +extern INT32 mcl_sendto (INT32 id, const void *data, INT32 len, + const struct sockaddr *saddr, INT32 saddr_len); + +/** + * mcl_recv data reception function. + * + * @param id MCL session identifier + * @param buf pointer to data buffer + * @param len data buffer length in bytes + * @return number of bytes received or -1 if error + */ +extern INT32 mcl_recv (INT32 id, void *buf, INT32 len); + +/** + * mcl_recvfrom data reception function. + * + * @param id MCL session identifier + * @param data pointer to data buffer + * @param len data buffer length in bytes + * @param saddr source address from which data was received + * (so far only AF_INET is supported) + * @param saddr_len pointer to address length (sockaddr struct is generic!). + * This argument is modified by mcl_recvfrom to contain + * the actual length of the address at function return. + * @return number of bytes received or -1 if error + */ +extern INT32 mcl_recvfrom (INT32 id, void * buf, INT32 len, + struct sockaddr *saddr, INT32 *saddr_len); + +#ifdef ALC /* { */ +/** + * Flags that can be used by the mcl_sndmsg/mcl_recvmsg functions. + */ +enum mcl_msgflag { + MCL_MSG_DEFAULT = 0, /* This flag is the default behavior. */ + /* At a receiver, copy data and remove it */ + /* from the received and decoded object list, */ + /* at a sender, add data to the object list. */ +#if 0 /* not yet */ + MCL_MSG_PEEK, /* This flag causes the receive operation */ + /* to return data from the beginning of the */ + /* receive queue without removing that data */ + /* from the queue. Thus, the following */ + /* receive call will return the same data. */ +#endif + MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT + /* This flag causes the receive application */ + /* to return the amount of data available for */ + /* a future read, as well as the associated + * TOI. Usefull to have an idea of the buffer */ + /* size required for a future read, and/or */ + /* determining which object is available when */ + /* used with FLUTE. This call requires to */ + /* use a mcl_msghdr struct, with a null iov */ + /* array (msg_iov = NULL && msg_iovlen=0). */ + /* When mcl_recvmsg is called with this flag, */ + /* the subsequent mcl_recv/recv_flute/recvmsg */ + /* call MUST return the same object. */ + /* This flag is not valid at a sender. */ +}; + + +/** + * Structure for scatter/gather I/O, and used by the mcl_sndmsg/mcl_recvmsg + * functions. + */ +struct mcl_iovec { + INT32 iov_type; /* type of storage (file or buffer) */ + void *iov_base; /* pointer to buffer storage area in */ + /* MCL_IOV_TYPE_BUFFER mode */ + char *iov_filename; /* file name to be used as storage area in */ + /* MCL_IOV_TYPE_FILE mode */ + INT64 iov_offset; /* file offset from begining of file, in */ + /* MCL_IOV_TYPE_FILE type */ + INT64 iov_len; /* length to consider in buffer or file */ +}; + +#define MCL_IOV_TYPE_BUFFER 0 +#define MCL_IOV_TYPE_FILE 1 + + +/** + * Message control structure used by mcl_sndmsg/mcl_recvmsg functions. + */ +struct mcl_msghdr { + void *msg_name; /* optional address. When present, */ + /* it must point to a sockaddr struct */ + INT32 msg_namelen; /* size of address. When present, */ + /* it must be equal to */ + /* sizeof(struct sockaddr_in[6]) */ + struct mcl_iovec *msg_iov; /* scatter/gather array */ + INT32 msg_iovlen; /* number of elements in msg_iov */ + //void *msg_control; /* ancillary data, see below */ + //INT32 msg_controllen; /* ancillary data buffer len */ + //INT32 msg_flags; /* flags on received message */ + UINT64 toi; /* transport object ID. */ + /* Updated by mcl_recvmsg() */ +}; + + +/** + * mcl_sendmsg extended data transmission function. + * This function, similar in spirit to sendmsg, enables a full control of + * what data is submitted by the application at the price of a higher + * complexity. For instance, data from a file, at an appropriate offset, + * can be submitted directly, or gathered from several buffers/files (or + * any mix of them) to the same ALC object, etc. + * WARNING: in current implementation, a single iovec entry is assumed + * (i.e. does not support data gathering)! + * + * @param id MCL session identifier + * @param msg pointer to the mcl_msghdr structure. + * @param flags flags to control some specific features. + * @return number of bytes sent, or -1 if an error occured. + */ +extern INT64 mcl_sendmsg (INT32 id, struct mcl_msghdr *msg, + mcl_msgflag flags); + + +/** + * mcl_recvmsg extended data reception function. + * This function, similar in spirit to recvmsg, enables a full control of + * what data is returned to the application at the price of a higher + * complexity. For instance, data can be stored directly to a file, at + * an apprppriate offset, or scattered into several different buffers/files + * (or any mix of them), etc. + * + * @param id MCL session identifier + * @param msg pointer to the mcl_msghdr structure. + * @param flags flags to control some specific features. + * @return number of bytes received (or available if MCL_MSG_PEEK or + * MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT are used), or -1 if + * an error occured. + */ +extern INT64 mcl_recvmsg (INT32 id, struct mcl_msghdr *msg, + mcl_msgflag flags); +#endif /* } ALC */ + + +#ifdef ALC +/** + * mcl_wait_event waits (i.e. blocks) until a given event takes + * place and then returns. + * This function is only defined with MCL-ALC sessions. + * + * @param id MCL session identifier + * @param event event type + * @return 0 if ok, -1 if error + */ +extern INT32 mcl_wait_event (INT32 id, INT32 event); + + +/** + * mcl_select waits until an event occured in one of its file + * descriptors or until it timeout's. + * This function currently has many limitations: + * - it only waits until on readfs descriptors, other file descriptor + * pointers must be NULL + * - it only considers a single readfds, waiting on multiple MCL sessions + * is not supported + * - only MCL session descriptors can be specified in the file descriptor + * set. It is not possible to mix non-MCL and MCL descriptors + * - it is only available on MCL-ALC sessions. + * The behavior and parameters are otherwise similar to that of the + * socket select() system call. + * @param n max MCL session identifier plus 1 + * @param readfs table of MCL session identifier (only one is + * currently possible) + * @param writefs not supported, must be NULL + * @param exceptfs not supported, must be NULL + * @param timeout pointer to a timeval structure, indicating how + * long select can wait. If NULL, this function + * returns immediately + * @return On success, it return the number of descriptors contained + * in the descriptor sets, which may be zero if the timeout + * expires before anything interesting happens. + * On error -1 is returned and errno is set appropriately; + * the sets and timeout become undefined, so do not rely on + * their contents after an error. + */ +extern INT32 mcl_select (INT32 n, fd_set *readfds, fd_set *writefds, + fd_set *exceptfds, struct timeval *timeout); + + +/* + * for mcl_wait_event... + */ +#define MCL_WAIT_EVENT_END_TX 0 +#define MCL_WAIT_EVENT_END_RX 1 +#define MCL_WAIT_EVENT_CLOSED 2 + +#endif /* ALC */ + + +#endif /* MCL_LIB_API_H */ diff --git a/src/common/mcl_list.cpp b/src/common/mcl_list.cpp new file mode 100644 index 0000000..610f322 --- /dev/null +++ b/src/common/mcl_list.cpp @@ -0,0 +1,242 @@ +/* $Id: mcl_list.cpp,v 1.3 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef ALC +#include "../alc/mcl_includes.h" + +#elif defined(NORM) + +#include "../norm/mcl_includes.h" +#endif // RM_PROTOCOL + + +#if 0 +/** + * Default constructor. + */ +template +mcl_seq_list::mcl_seq_list () +{ + this->m_head = NULL; + this->m_size = 0; + this->m_find_cache = NULL; +} + + +/** + * Default destructor. + */ +template +mcl_seq_list::~mcl_seq_list () +{ + // remove everything and call delete for each element + this->remove_all(this->m_delete_callback); +} + + +/** + * Insert an element in an ordered list according to its sequence + * number. + * See header file for more information. + */ +template +mcl_error_status +mcl_seq_list::insert (//mcl_cb *const mclcb, + T *elem) +{ + T *pe, *ne; // insert elem between prev/next elem + + ASSERT(elem->next == NULL && elem->prev == NULL); // single elem to add + TRACELVL(5, (mcl_stdout, "-> mcl_seq_list::insert: du=x%x\n", (int)this)) + /* + * find last element in list, i.e. with highest seq nb + */ + if (this->m_head == NULL || (this->m_head)->prev == NULL) { + /* first element in empty list */ + this->m_head = elem; + this->m_size = 1; + elem->next = elem->prev = elem; + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::insert: first\n")) + return MCL_OK; + } + pe = this->m_head->prev; + ne = pe->next; + /* + * find the proper location of elem in the list to make + * sure seq numbers are always increasing + */ + while (elem->seq < pe->seq) { + ne = pe; + pe = pe->prev; + if (ne == this->m_head) { + /* we have cycled ! elem is the new list head */ + this->m_head = elem; + break; + } + } + if (elem->seq == pe->seq) { + /* elem already received */ + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::insert: ERROR, already in list\n")) + return MCL_ERROR; + } else { + /* elem DU */ + pe->next = elem; + elem->prev = pe; + elem->next = ne; + ne->prev = elem; + this->m_size++; + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::insert: new\n")) + return MCL_OK; + } +} + + +/** + * + * See header file for more information. + */ +template +mcl_error_status +mcl_seq_list::remove (T *elem) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_seq_list::remove: elem->seq=%d\n", elem->seq)) + if (this->find(elem->seq) == NULL) { + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::remove: ERROR, not found in list\n")) + return MCL_ERROR; + } + ASSERT(elem->prev != NULL && elem->next != NULL); + elem->prev->next = elem->next; + elem->next->prev = elem->prev; + if (this->m_head == elem) { + // elem->next since seq is kept in increasing order + this->m_head = elem->next; + } + this->m_find_cache = NULL; // invalidate cache which always points + // to elem (find() is called just above) + this->m_size--; + return MCL_OK; +} + + +/** + * + * See header file for more information. + */ +template +mcl_error_status +mcl_seq_list::remove_all (void (*func) (T*)) +{ + T *e, *ne; // current elem and next elem + + TRACELVL(5, (mcl_stdout, "-> mcl_seq_list::remove_all\n")) + e = this->m_head; + if (e == NULL) { + ASSERT(this->m_size == 0); + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::remove_all: empty list\n")) + return MCL_OK; + } + do { + ne = e->next; + if (func) { + func(e); + } + e = ne; +#ifdef DEBUG + this->m_size--; +#endif + } while (e != this->m_head); + ASSERT(this->m_size == 0); + this->m_size = 0; + this->m_head = NULL; + this->m_find_cache = NULL; + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::remove_all: ok\n")) + return MCL_OK; +} + + + +/** + * + * See header file for more information. + */ +template +T * +mcl_seq_list::find (INT32 s) +{ + T *e; + + TRACELVL(5, (mcl_stdout, "-> mcl_seq_list::find: seq=%d\n", s)) + e = this->m_head; + if (e == NULL) { + ASSERT(this->m_size == 0); + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::find: empty list\n")) + return NULL; + } + if (this->m_find_cache && this->m_find_cache->seq == s) { + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::find: found in cache\n")) + return this->m_find_cache; + } + /* + * start from the highest seq number + */ + e = e->prev; + while (1) { + ASSERT(e); + if (e->seq == s) { + /* found */ + this->m_find_cache = e; + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::find: found\n")) + return e; + } + if (e == this->m_head || e->seq < s) { + /* we have cycled or new element cannot be in list */ + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::find: new\n")) + return NULL; + } + e = e->prev; + } +} + + +/** + * + * See header file for more information. + */ +template +void +mcl_seq_list::print_all (void) +{ + T *e; // current elem + + TRACELVL(5, (mcl_stdout, "-> mcl_seq_list::print_all\n")) + e = this->m_head; + if (e == NULL) { + ASSERT(this->m_size == 0); + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::print_all: empty list\n")) + return; + } + do { + e->print(); + e = e->next; + } while (e != this->m_head); + TRACELVL(5, (mcl_stdout, "<- mcl_seq_list::print_all: ok\n")) +} +#endif // 0 diff --git a/src/common/mcl_list.h b/src/common/mcl_list.h new file mode 100644 index 0000000..4d592ca --- /dev/null +++ b/src/common/mcl_list.h @@ -0,0 +1,294 @@ +/* $Id: mcl_list.h,v 1.3 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_LIST_H +#define MCL_LIST_H + +#if 0 // { +/** + * Ordered linked list class with sequential access to elements. + * + * Assumes that elements already have next/prev pointer members + * AND a seq member value which will be used to sort elements. + * A print() method is also required if it is desired to print the + * list content with the print_all() method. + * + * Search operations follow a linear search algorithm, so this class + * is limited to small lists. + * This class does not allocate any data, hence its efficiency compared + * to the variants based on containers. + * Yet a limitation is that an element cannot belong simultaneously + * to two or more lists since there is a single instance of prev/next + * pointers. + */ +template +class mcl_seq_list +{ + +public: + /** + * Default constructor. + */ + mcl_seq_list (); + + /** + * Default destructor. + * Remove and delete all elements of the list, calling the + * default destructor of these elements. + */ + ~mcl_seq_list (); + + /** + * Insert an element in an ordered list according to its sequence + * number. + * Insert the element at its location (i.e. to comply + * with the increasing seq # property) in the list. + * @param mclcb + * @param elem element to insert in list + * @return completion status: MCL_OK if inserted, or MCL_ERROR + * if already present in list. + */ + mcl_error_status insert (T *elem); + + /** + * Remove an element from the list. + * This method does not try to free the element. + * @param mclcb + * @param elem element to remove from the list + * @return completion status: MCL_OK if removed, or MCL_ERROR + * if not found in list or in case of error. + */ + mcl_error_status remove (T *elem); + + /** + * Remove all elements from the list. + * This method does not try to free the elements but instead + * calls the callback function provided for each element. + * @param mclcb + * @param func callback function that needs to be called + * for each element removed from the list, or NULL + * if nothing shall be done + * @return completion status: MCL_OK if removed, or MCL_ERROR + * in case of error. + */ + mcl_error_status remove_all (void (*func)(T*)); + + /** + * Find the element with the given sequence number in an ordered list. + * @param mclcb + * @param seq sequence number looked for + * @return pointer to the element with that sequence number + * if found, NULL if not found or in case of error. + */ + T *find (INT32 seq); + + /** + * Return the first element of list. + * @return pointer to the first element of this sequentially + * ordered list, or NULL if list is empty. + */ + T *first (void); + + /** + * Return the last element of list. + * @return pointer to the last element of this sequentially + * ordered list, or NULL if list is empty. + */ + T *last (void); + + /** + * Number of elements in list. + * @return total number of elements in list + */ + INT32 size (void); + + /** + * Call the print method of each element in list. + * Traversal of list is done in increasing sequence number order. + */ + void print_all (void); + + +private: + T *m_head; // pointer to first element of list + INT32 m_size; // number of elements in list + T *m_find_cache; // cache used by the find method + + static void m_delete_callback (T *elem);// used by default destructor + // to delete each element +}; + + +/** + * Ordered table class. + * + * Assumes that elements already have a seq member value which is + * also used as the index in the tablE. + * A print() method is also required if it is desired to print the + * list content with the print_all() method. + * + * This class does not allocate any data, hence its efficiency compared + * to the variants based on containers. + * Yet a limitation is that an element cannot belong simultaneously + * to two or more lists since there is a single instance of prev/next + * pointers. + * Another limitation is that the table cannot be extended once + * created. + */ +template +class mcl_seq_table +{ + +public: + /** + * Constructor. + * The table has a fixed size, initialized upon creation. + * No size modification will be possible later on. + * @param size number of elements in the table. + */ + mcl_seq_table (INT32 size); + + /** + * Default destructor. + * Remove and delete all elements of the table, calling the + * default destructor of these elements. + */ + ~mcl_seq_table (); + + /** + * Insert an element in an ordered table according to its sequence + * number. + * Insert the element at its location (i.e. to comply + * with the increasing seq # property) in the table. + * @param mclcb + * @param elem element to insert in table + * @return completion status: MCL_OK if inserted, or MCL_ERROR + * if already present in table. + */ + mcl_error_status insert (T *elem); + + /** + * Remove an element from the table. + * This method does not try to free the element. + * @param mclcb + * @param elem element to remove from the table + * @return completion status: MCL_OK if removed, or MCL_ERROR + * if not found in table or in case of error. + */ + mcl_error_status remove (T *elem); + + /** + * Remove all elements from the table. + * This method does not try to free the elements but instead + * calls the callback function provided for each element. + * @param mclcb + * @param func callback function that needs to be called + * for each element removed from the table, or NULL + * if nothing shall be done + * @return completion status: MCL_OK if removed, or MCL_ERROR + * in case of error. + */ + mcl_error_status remove_all (void (*func)(T*)); + + /** + * Find the element with the given sequence number in an ordered table. + * @param mclcb + * @param seq sequence number looked for + * @return pointer to the element with that sequence number + * if found, NULL if not found or in case of error. + */ + T *find (INT32 seq); + + /** + * Return the first element of table. + * @return pointer to the first element of this sequentially + * ordered table, or NULL if table is empty. + */ + T *first (void); + + /** + * Return the last element of table. + * @return pointer to the last element of this sequentially + * ordered table, or NULL if table is empty. + */ + T *last (void); + + /** + * Number of elements in table. + * @return total number of elements in table + */ + INT32 size (void); + + /** + * Call the print method of each element in table. + * Traversal of table is done in increasing sequence number order. + */ + void print_all (void); + + +private: + T *m_head; // pointer to first element of table + INT32 m_size; // number of elements in table + + static void m_delete_callback (T *elem);// used by default destructor + // to delete each element +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +template +inline INT32 +mcl_seq_list::size () +{ + return this->m_size; +} + +template +inline void +mcl_seq_list::m_delete_callback (T *elem) +{ +#if 0 + elem->print(); +#endif + delete elem; +} + +template +inline T * +mcl_seq_list::first (void) +{ + return m_head; +} + +template +inline T * +mcl_seq_list::last (void) +{ + return m_head->prev; +} + +#endif // } 0 +#endif // MCL_LIST_H + diff --git a/src/common/mcl_osdep.cpp b/src/common/mcl_osdep.cpp new file mode 100644 index 0000000..e4ed9c6 --- /dev/null +++ b/src/common/mcl_osdep.cpp @@ -0,0 +1,321 @@ +/* $Id: mcl_osdep.cpp,v 1.10 2004/12/10 13:21:12 chneuman Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * OS dependant code + */ + +#ifdef ALC +#include "../alc/mcl_includes.h" + +#elif defined(NORM) + +#include "../norm/mcl_includes.h" +extern void mcl_exit (int n); +#endif // ALC|NORM + + + +/** + * initialize a mutex lock + * @param mutex mutex to initialize + */ +void +mcl_init_lock (mcl_mutex_t *mutex) +{ +#if defined(WIN32) + InitializeCriticalSection(mutex); +#else + { + pthread_mutex_t mutex_init = PTHREAD_MUTEX_INITIALIZER; + memcpy(mutex, &mutex_init, sizeof(pthread_mutex_t)); + } +#endif +} + + +//#ifdef ALC +#ifdef NEVERDEF +/** + * get the MCL global lock + * @param mclcb + */ +void +mcl_global_lock (mcl_cb *mclcb) +{ + mcl_lock(&mcl_mutex_lock); +} +#endif // ALC + + +/** + * get this lock + * @param mutex mutex lock + */ +void +mcl_lock (mcl_mutex_t *mutex) +{ +#ifdef WIN32 + EnterCriticalSection(mutex); +#else + pthread_mutex_lock(mutex); +#endif /* OS_DEP */ +} + + +/* + * try to get a lock + * @param mclcb + * @return return EBUSY if not possible, 0 if ok + */ +int +mcl_trylock (mcl_mutex_t *mutex) +{ +#ifdef WIN32 + return 1; /* non 0 to simulate error */ +#else + return pthread_mutex_trylock(mutex); +#endif /* OS_DEP */ +} + + +/** + * release a lock + * @param mutex mutex lock + */ +void +mcl_unlock (mcl_mutex_t *mutex) +{ +#ifdef WIN32 + LeaveCriticalSection(mutex); +#else + pthread_mutex_unlock(mutex); +#endif /* OS_DEP */ +} + + +#ifdef ALC +void +mcl_thread_testcancel (mcl_cb *mclcb) +{ +#ifdef WIN32 + if(mclcb->test_cancel == true) { + ExitThread(0); + } +#else /* UNIX */ + pthread_testcancel(); +#endif +} +#endif /* ALC */ + + +/** + * portable micro sleep + * replaces: void usleep(unsigned long usec) + * while conserving the same prototype + * @ param usec time to sleep in micro-seconds + */ +void +mcl_usleep (unsigned long usec) +{ +#ifdef WIN32 + Sleep(max(usec,1000)/1000); +#elif defined(LINUX) + usleep(usec); +#else + struct timeval tv; + + tv.tv_sec = ceil(usec / 1000000); + tv.tv_usec = usec % 1000000; + if (select(0, NULL, NULL, NULL, &tv) < 0) { + if (errno != EINTR) { + perror("mcl_usleep: ERROR"); + mcl_exit(-1); + } + } +#endif /* OS_DEP */ +} + + +/** + * portable gettimeofday + * @return returns 0 if ok, -1 if error, like the unix gettimeofday function + */ +int +mcl_gettimeofday (struct timeval *time) +{ +#ifdef WIN32 + UINT32 Gtime; + Gtime = timeGetTime(); + time->tv_sec = Gtime/1000; + time->tv_usec = (Gtime%1000)*1000; + return 0; +#else /* UNIX */ + return gettimeofday(time, NULL); +#endif /* OS_DEP */ +} + + +#ifdef SOLARIS +/** + * inet_aton replacement for SOLARIS that doesn't include it. + * feel free to comment if already available on your system... + * + * int inet_aton(const char *cp, struct in_addr *inp); + * + * inet_aton() converts the Internet host address cp from the + * standard numbers-and-dots notation into binary data and + * stores it in the structure that inp points to. inet_aton + * returns nonzero if the address is valid, zero if not. + */ +int inet_aton(const char *cp, struct in_addr *inp) +{ + // use a wrapup around: in_addr_t inet_addr(const char *cp); + inp->s_addr = inet_addr(cp); + if ((int)inp->s_addr == -1) + return 0; /* failed, bad addr */ + else + return 1; /* ok */ +} +#endif // SOLARIS + + +/* + * MAD-ALC, implementation of ALC/LCT protocols + * Copyright (c) 2003 TUT - Tampere University of Technology + * main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.fi + */ +/** + * This function converts double value to the closest integer value. + * Usefull if the double value can have small calculation errors. + * @params value value to be converted. + * @return converted integer value. + */ +INT32 +double_to_closest_int (double value) +{ + double ceil_value; + double floor_value; + double abs_diff1; + double abs_diff2; + + ceil_value = ceil(value); + floor_value = floor(value); + abs_diff1 = fabs(value - ceil_value); + abs_diff2 = fabs(value - floor_value); + if (abs_diff1 < abs_diff2) { + return((INT32)ceil_value); + } else { + return((INT32)floor_value); + } +} + + +#ifdef WIN32 +/** + * rint replacement for Windows that does not include it. + * Prototype: + * double rint(double x); + */ +double +rint (double value) +{ + double ceil_value; + double floor_value; + double abs_diff1; + double abs_diff2; + + ceil_value = ceil(value); + floor_value = floor(value); + abs_diff1 = fabs(value - ceil_value); + abs_diff2 = fabs(value - floor_value); + if (abs_diff1 < abs_diff2) { + return(ceil_value); + } else { + return(floor_value); + } +} +#endif // WIN32 + + +/** + * initialize srandom seed + */ +void +mcl_init_random () +{ + struct timeval tmp = mcl_get_tvtime(); /* to improve randomness */ + +#ifdef WIN32 + srand(tmp.tv_usec); +#else + srandom(tmp.tv_usec); +#endif +} + + +#ifdef WIN32 +/** + * Socket initialisation for WinSock + */ +void +mcl_winsock_init () +{ + int err = 0; + WSADATA wsaData; + WORD wVersionRequested = MAKEWORD( 2, 2 ); + + err = WSAStartup( wVersionRequested, &wsaData ); + if ( err != 0 ) { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + printf("mcl_winsock_init: Unable to initialize Winsock DLL (step 1)\n"); + mcl_exit(-1); + } + /* Confirm that the WinSock DLL supports 2.2.*/ + /* Note that if the DLL supports versions greater */ + /* than 2.2 in addition to 2.2, it will still return */ + /* 2.2 in wVersion since that is the version we */ + /* requested. */ + if( LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2 ) + { + /* Tell the user that we could not find a usable */ + /* WinSock DLL. */ + perror("mcl_winsock_init: Unable to initialize Winsock DLL (step 2)"); + WSACleanup( ); + mcl_exit(1); + } +} + +bool mcl_is_valid_sock (SOCKET sock) +{ + return ((sock == INVALID_SOCKET || (int)sock <= 0 || + sock == SOCKET_ERROR) ? false : true); +} + +#else /* UNIX */ + +bool mcl_is_valid_sock (int sock) +{ + return ((sock <= 0) ? false : true); +} + +#endif /* OS */ diff --git a/src/common/mcl_osdep.h b/src/common/mcl_osdep.h new file mode 100644 index 0000000..4a3c3d9 --- /dev/null +++ b/src/common/mcl_osdep.h @@ -0,0 +1,318 @@ +/* $Id: mcl_osdep.h,v 1.16 2004/12/02 11:49:22 chneuman Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * OS dependant code + */ +#ifndef _MCL_OSDEP_H_ +#define _MCL_OSDEP_H_ + +/* + * Since Linux is multi-platform, we define here two possible target + * environments: + * - i386 for Intel/AMD hosts + * - ppc for PowerPC hosts + * Change it as required (there's no automatic discovery)... + * This is used in particular for bit-field order (see below). + */ +#ifdef LINUX +#define LINUX_I386 /* default */ +/*#define LINUX_PPC*/ /* uncomment if needed */ +#endif + + +/* + * bit field order is compiler/OS dependant + * With linux, see the above LINUX_XXX defines... + */ +#if defined(LINUX_I386) || defined(WIN32) || defined (FREEBSD) +#define _BIT_FIELDS_LTOH +#undef _BIT_FIELDS_HTOL + +#elif defined(SOLARIS) || defined(LINUX_PPC) || defined(AIX) || defined(HPUX) + +#undef _BIT_FIELDS_LTOH +#define _BIT_FIELDS_HTOL /* SunSparc is HtoL */ +#endif + + +/* + * sighandler + */ +#if defined(LINUX) || defined (FREEBSD) + /* On Linux systems, signal handlers must be of __sighandler_t type */ +#define sighandler_t __sighandler_t + +#elif defined(SOLARIS) + +#define sighandler_t void (*)(int) +#endif /* OS */ + + +/* + * thread management functions and types + */ +#if defined(WIN32) +#define mcl_mutex_t CRITICAL_SECTION +#define mcl_thread_t HANDLE +#else /* UNIX */ +#define mcl_mutex_t pthread_mutex_t +#define mcl_thread_t pthread_t +#endif /* OS */ + + +/* + * mode_t for WIN32 + */ +#ifdef WIN32 +#define mode_t int +#endif + +/* + * socket and iovec structure macros for sendmsg/recvmsg syscalls + */ +#ifdef WIN32 +#define MCL_SOCKET SOCKET +#define random rand +#define dup _dup +#define MCL_IOVEC WSABUF +#define MCL_IOV_BUFF(x) x.buf +#define MCL_IOV_LEN(x) x.len +#define MCL_IOV_BUFF_TYPE + +#else /* UNIX */ + +#define MCL_SOCKET int +#define MCL_IOVEC struct iovec +#define MCL_IOV_BUFF(x) x.iov_base +#define MCL_IOV_LEN(x) x.iov_len + +#if defined(SOLARIS) +#define MCL_IOV_BUFF_TYPE caddr_t +#elif defined(FREEBSD) +#define MCL_IOV_BUFF_TYPE char* +#else +#define MCL_IOV_BUFF_TYPE void* +#endif + +#endif /* OS */ + + +/** + * Rounding functions + */ +extern INT32 double_to_closest_int (double value); +#ifdef WIN32 +extern double rint (double value); +#endif /* WIN32 */ + + +/* + * various stuff + */ +#ifdef WIN32 +#define random rand +#define dup _dup +#else +#endif /* OS */ + + +#ifdef SOLARIS +/** + * inet_aton replacement for SOLARIS that doesn't include it + * feel free to comment if already available on your system... + */ +extern int inet_aton(const char *cp, struct in_addr *inp); +#endif // SOLARIS + + +/* + * MCL prototypes + */ +extern void mcl_init_lock (mcl_mutex_t *mutex); +extern void mcl_lock (mcl_mutex_t *mutex); +extern int mcl_trylock (mcl_mutex_t *mutex); +extern void mcl_unlock (mcl_mutex_t *mutex); +#ifdef ALC +extern void mcl_thread_testcancel (class mcl_cb *mclcb); +#endif + +extern void mcl_usleep (unsigned long usec); +extern int mcl_gettimeofday (struct timeval*tv); +extern void mcl_init_random (void); +#ifdef WIN32 +extern void mcl_winsock_init (void); +extern bool mcl_is_valid_sock (SOCKET sock); +#else // UNIX +extern bool mcl_is_valid_sock (INT32 sock); +#endif // OS + + +#ifdef NORM /* { */ + +/* + * The following defines are required by RMF code + */ + +#if defined(LINUX) || defined(SOLARIS) || defined(FREEBSD) + +//============================================================================ +// NON-WIN32 SECTION +//============================================================================ + +#define mcl_STATIC_VOID_METHOD static void * +#define mcl_VOID_METHOD void * +#define mcl_SOCKET_TYPE int +#define mcl_OPTVAL_TYPE void * +#define mcl_TTL_TYPE unsigned char + + +//============================================================================ +// Mutex Section for non-Win32 Platforms -- Begin +//============================================================================ + +#define mcl_MUTEX_TYPE pthread_mutex_t +#define mcl_MUTEX_CONST_INIT PTHREAD_MUTEX_INITIALIZER + +#define mcl_MUTEX_INIT pthread_mutex_init +#define mcl_MUTEX_DESTROY pthread_mutex_destroy +#define mcl_MUTEX_LOCK pthread_mutex_lock +#define mcl_MUTEX_UNLOCK pthread_mutex_unlock + + +//============================================================================ +inline +INT32 mcl_MUTEX_STATIC_INIT(mcl_MUTEX_TYPE * m) +{ + return 0; +} + + +//============================================================================ +// Mutex Section for non-Win32 Platforms -- End +//============================================================================ + + +//============================================================================ +// Condition Variable Section for non-Win32 Platforms -- Begin +//============================================================================ + +#define mcl_COND_VAR_TYPE pthread_cond_t +#define mcl_COND_VAR_ATTR_TYPE pthread_condattr_t + +#define mcl_COND_VAR_INIT pthread_cond_init +#define mcl_COND_VAR_DESTROY pthread_cond_destroy +#define mcl_COND_VAR_WAIT pthread_cond_wait +#define mcl_COND_VAR_BROADCAST pthread_cond_broadcast + + +//============================================================================ +inline +INT32 mcl_COND_VAR_TIMEDWAIT(mcl_COND_VAR_TYPE * c, mcl_MUTEX_TYPE * m, + INT32 msec) +{ + struct timeval tv; + struct timespec ts; + +#define GETTIMEOFDAY_NULL_ARG +#ifdef GETTIMEOFDAY_NULL_ARG + gettimeofday(&tv, NULL); +#else + gettimeofday(&tv); +#endif + + tv.tv_usec += (msec * 1000); + tv.tv_sec += (tv.tv_usec / 1000000); + tv.tv_usec = (tv.tv_usec % 1000000); + + ts.tv_sec = tv.tv_sec; + ts.tv_nsec = ((tv.tv_usec * 1000) + (msec * 1000000)); + + return pthread_cond_timedwait(c, m, &ts); +} + + +//============================================================================ +// Condition Variable Section for non-Win32 Platforms -- End +//============================================================================ + + +//============================================================================ +// Thread Section for non-Win32 platforms -- Begin +//============================================================================ + +typedef void *(*mcl_THREAD_FUNC_DEF)(void *); + +#define mcl_THREAD_TYPE pthread_t +#define mcl_THREAD_ATTR_TYPE pthread_attr_t +#define mcl_THREAD_ATTR_PTR mcl_THREAD_ATTR_TYPE * +#define mcl_THREAD_FUNC mcl_THREAD_FUNC_DEF +#define mcl_THREAD_ARG void * + +#define mcl_CONST_CANCEL_ENABLE PTHREAD_CANCEL_ENABLE +#define mcl_CONST_CANCEL_DEFERRED PTHREAD_CANCEL_DEFERRED +#define mcl_CONST_CREATE_DETACHED PTHREAD_CREATE_DETACHED + +#define mcl_THREAD_ATTR_INIT pthread_attr_init +#define mcl_THREAD_ATTR_SETDETACHSTATE pthread_attr_setdetachstate +#define mcl_THREAD_ATTR_DESTROY pthread_attr_destroy +#define mcl_THREAD_CREATE pthread_create +#define mcl_THREAD_JOIN pthread_join +#define mcl_THREAD_DETACH pthread_detach +#define mcl_THREAD_KILL pthread_cancel +#define mcl_THREAD_CANCEL_STATE pthread_setcancelstate +#define mcl_THREAD_CANCEL_TYPE pthread_setcanceltype +#define mcl_THREAD_TEST_CANCEL pthread_testcancel +#define mcl_THREAD_YIELD sched_yield + + +//============================================================================ +inline +INT32 mcl_SIGNAL_BLOCK_MASK(INT32 signal) +{ + sigset_t blockedsignals; + + sigemptyset(&blockedsignals); + sigaddset(&blockedsignals, signal); + return pthread_sigmask(SIG_BLOCK, &blockedsignals, NULL); +} + + +//============================================================================ +// Thread Section for non-Win32 platforms -- End +//============================================================================ + + +//============================================================================ +inline +void mcl_INIT_WIN_SOCKETS() +{ + +} + +#elif defined(WIN32) + +TO DO... + +#endif // OS_DEP + +#endif /* } NORM */ +#endif /* _MCL_OSDEP_H_ */ diff --git a/src/common/mcl_periodic_timer.cpp b/src/common/mcl_periodic_timer.cpp new file mode 100644 index 0000000..424175f --- /dev/null +++ b/src/common/mcl_periodic_timer.cpp @@ -0,0 +1,144 @@ +/* $Id: mcl_periodic_timer.cpp,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef ALC +#include "../alc/mcl_includes.h" + +#elif defined(NORM) + +#include "../norm/mcl_includes.h" +#endif // ALC|NORM + + +/****** mcl_periodic_timer class **********************************************/ + + +/* static data members init */ +bool mcl_periodic_timer::no_time_to_sleep = false; +mcl_thread_t mcl_periodic_timer::timer_thread_id = 0; + + +void +mcl_periodic_timer::start () +{ +#ifdef DEBUG + static bool initialized = false; + + ASSERT(initialized == false); // check that it is called only once + initialized = true; +#endif + + mcl_periodic_timer::no_time_to_sleep = false; + /* + * create the timer thread... + */ +#ifdef WIN32 + if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mcl_periodic_timer::timer_thread, + NULL, 0, (LPDWORD)&(mcl_periodic_timer::timer_thread_id)) == NULL) { + perror("mcl_periodic_timer::start: CreateThread"); + mcl_exit(1); + } +#else + if (pthread_create((pthread_t*)&(mcl_periodic_timer::timer_thread_id), + NULL, mcl_periodic_timer::timer_thread, + (void*)NULL) != 0) { + perror("mcl_periodic_timer::start: pthread_create"); + mcl_exit(1); + } +#endif +} + + +/** + * Timer thread, with a 1/MCL_TIMER_PERIOD fixed frequency + * The mcl_time_count global variable, which reflects the nb of "ticks" + * elapsed since the begining, is updated here. + */ +void * +mcl_periodic_timer::timer_thread (void *arg) +{ + //INT32 ses; // session id + //mcl_cb *mclcb; // session control block + mcl_itime_t start_itime; // to calculate exact time to sleep + mcl_itime_t end_itime; // to calculate exact time to sleep + INT32 dt; // time diff in microseconds + INT32 dt2sleep; // sleep that nb of microseconds + mcl_itime_t timer_thread_last_wakeup; + // last time timer_thread woke up + float timer_thread_rem_tc; // fractional part of time_count + float true_tc; // elapsed time_count as a float + INT32 tc; // integral part of true_tc + + start_itime = mcl_get_itime(); + timer_thread_last_wakeup = start_itime; + timer_thread_rem_tc = 0.0; + + while (1) { + /* + * this sleep determines the timer granularity... + * it takes into account the processing time spent in the + * various calls to mcl_do_periodic_proc() + */ + end_itime = mcl_get_itime(); + dt = mcl_it2usec(mcl_itime_sub(end_itime, start_itime)); + // don't sleep less than 0.1ms + dt2sleep = max(100, (int)MCL_PERIODIC_TIMER_PERIOD - dt); + dt2sleep = min(MCL_PERIODIC_TIMER_PERIOD, dt2sleep); + if (dt2sleep == 100) { + no_time_to_sleep = true; +//#ifdef DEBUG +#if 0 + PRINT_ERR((mcl_stderr, "mcl_periodic_timer::timer_thread: WARNING, no time to sleep\n")) +#endif + } else { + no_time_to_sleep = false; + } + // now let's sleep... + mcl_usleep(dt2sleep); + start_itime = mcl_get_itime(); + + /* + * update the global MCL time (in time ticks), the + * mcl_time_count var. There is one tick every + * MCL_TIMER_PERIOD micro-seconds + */ + true_tc = (float)mcl_it2usec(mcl_itime_sub(start_itime, timer_thread_last_wakeup)) / (float)MCL_PERIODIC_TIMER_PERIOD + (float)timer_thread_rem_tc; + tc = (int)(true_tc); + mcl_time_count += tc; + //printf("THREAD:: start_itime=%d, timer_thread_last_wakeup=%d, timer_thread_rem_tc=%f, true_tc=%f, mcl_time_count=%d\n", start_itime, timer_thread_last_wakeup, timer_thread_rem_tc, true_tc, mcl_time_count); + timer_thread_last_wakeup = start_itime; + timer_thread_rem_tc = true_tc - tc; + + /* + * scan all the sessions... + * this is where the real work is done for each mcl_cb. + */ + mcl_periodic_proc::scan_all_sessions(); + } + arg = 0; +#ifdef WIN32 + ExitThread(0); +#else + pthread_exit(arg); +#endif + return arg; /* unused */ +} + diff --git a/src/common/mcl_periodic_timer.h b/src/common/mcl_periodic_timer.h new file mode 100644 index 0000000..c961e26 --- /dev/null +++ b/src/common/mcl_periodic_timer.h @@ -0,0 +1,134 @@ +/* $Id: mcl_periodic_timer.h,v 1.4 2005/05/17 12:36:59 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_PERIODIC_TIMER_H +#define MCL_PERIODIC_TIMER_H + + +/** + * Period of the main periodic timer. + * Used to trigger all the periodic processings (data transmissions + * essentially, congestion control periodic processing, etc.) + * This value (in microseconds) determines the internal MCL clock + * granularity. + * It is the sleep duration between two consecutive virtual time ticks. + * All other timers are multiples of this period... + */ +const INT32 MCL_PERIODIC_TIMER_PERIOD = 10000; // 10 ms => 100 Hz +//const INT32 MCL_PERIODIC_TIMER_PERIOD = 20000; // 20 ms => 50 Hz + + +/** + * MCL timer static class for periodic processing. + * There is only one instance of this class, allocated statically. + * + * Time is discretized into itime ticks (see src/common/mcl_itime.h|cpp). + * This class provides a timer that is to be used whenever dealing with + * periodic tasks. It is therefore different from the mcl_timer class + * which is dedicated to one-time timer events. + * For instance, mcl_periodic_timer is used for rate-controled transmissions. + * It is made possible by a dedicated thread that awakes regularly and + * calls the appropriate MCL functions that need periodic processing. + * The sleep duration takes into account the time spent in these functions + * and in case a large processing suspends temporarily the service, the + * various processing functions will be called as many times as required + * to compensate for the missed cycles. It guaranties that on average the + * period of each individual periodic processing functions is achieved. + * The mcl_time_count global variable, which reflects the nb of "ticks" + * elapsed since the begining, is updated here. + */ +class mcl_periodic_timer { + +public: + /****** Public Members ************************************************/ + + /** + * Starts the periodic_timer service. + * Exits in case of error. + */ + static void start (); + + /** + * Returns the periodic timer frequency in Hz. + */ + static double get_frequency (); + + /** + * Returns the periodic timer period in seconds. + */ + static double get_period (); + + /** + * Returns true if the activity is too high and transmission must be + * slown down. + */ + static bool must_reduce_activity (); + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + + /** + * Timer thread, with a 1/MCL_TIMER_PERIOD fixed frequency. + * @param arg unused + */ + static void *timer_thread (void *arg); + + /** + * Set the periodic timer frequency + */ + static void set_frequency (INT32 freq); + + /****** Private Attributes ********************************************/ + static bool no_time_to_sleep; + // true when the activity is far too high. + // This is symptomatic of a problem, so + // we must try to find a solution then... + static mcl_thread_t timer_thread_id; // idf returned at creation +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline double +mcl_periodic_timer::get_frequency () +{ + return ((double)1000000.0 / (double)MCL_PERIODIC_TIMER_PERIOD); +} + +inline double +mcl_periodic_timer::get_period () +{ + return (double)0.000001 * (double)MCL_PERIODIC_TIMER_PERIOD; +} + +inline bool +mcl_periodic_timer::must_reduce_activity () +{ + return no_time_to_sleep; +} + +#endif // !MCL_PERIODIC_TIMER_H + diff --git a/src/common/mcl_socket_lib.cpp b/src/common/mcl_socket_lib.cpp new file mode 100644 index 0000000..4c5db62 --- /dev/null +++ b/src/common/mcl_socket_lib.cpp @@ -0,0 +1,713 @@ +/* $Id: mcl_socket_lib.cpp,v 1.15 2005/05/24 15:43:23 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef ALC +#include "../alc/mcl_includes.h" + +#elif defined(NORM) + +#include "../norm/mcl_includes.h" +#endif // RM_PROTOCOL + + +/******************************************************************************/ +/* + * Code derived from Richard Stevens's book: + * "UNIX Network Programming, Volume 1, Second Edition: "Networking + * APIs: Sockets and XTI", Prentice Hall, 1998, ISBN 0-13-490012-X. + * Available at URL: http://www.kohala.com/start/unpv12e.html + */ + + +/** + * Set the multicast interface where to send or receiver multicast traffic. + * => See header file for more informations. + */ +INT32 +mcast_set_if (MCL_SOCKET sockfd, + INT32 af, + mcl_addr *ifaddr, + const char *ifname, + INT32 verbosity) +{ + INT32 err; + + if (verbosity >= 4) { + PRINT_OUT((mcl_stdout, + "mcast_set_if: af=%d, ifaddr=%s, ifname=%s\n", af, + (ifaddr != NULL) ? ifaddr->get_addr_string() : "null", + (ifname != NULL) ? ifname : "null")) + } + switch (af) { + case AF_INET: { + struct in_addr inaddr; + struct sockaddr_in sin; // used if ifaddr is provided +#ifndef WIN32 /* SIOCGIFADDR not defined in WinSock2? */ + struct ifreq ifreq; // used if ifname is provided + + if (ifname != NULL) { + strncpy(ifreq.ifr_name, ifname, IF_NAMESIZE); + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) { + /* i/f name not found */ + perror("mcast_set_if: ERROR, ioctl(SIOCGIFADDR)"); + PRINT_ERR((mcl_stderr, + "mcast_set_if: ERROR, ioctl(SIOCGIFADDR) failed for ifname %s\n", + ifname)) + errno = ENXIO; + return(-1); + } + memcpy(&inaddr, + &((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr, + sizeof(struct in_addr)); + } else +#endif /* OS */ + if (ifaddr != NULL) { + if (ifaddr->is_ipv4_addr() == false) { + PRINT_ERR((mcl_stderr, + "mcast_set_if: ERROR, ifaddr is IPv6 whereas the declared address family is IPv4!\n")) + errno = EINVAL; + return(-1); + } + ifaddr->get_addr_struct(&sin); + memcpy(&inaddr, &((struct sockaddr_in*)&sin)->sin_addr, + sizeof(struct in_addr)); + } else { + /* Remove previous. Set interface to default */ + inaddr.s_addr = htonl(INADDR_ANY); + } + if ((err = setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_IF, + (char*)&inaddr, sizeof(struct in_addr))) < 0) { + int e = errno; + perror("mcast_set_if: ERROR, setsockopt(IP_MULTICAST_IF)"); + errno = e; + return(-1); + } + return (err); + } +#ifdef INET6 + case AF_INET6: { + u_int index; + +#ifndef WIN32 + if (ifname == NULL) { + /* must supply name */ + PRINT_ERR((mcl_stderr, + "mcast_set_if: ERROR, ifname required\n")) + errno = EINVAL; + return(-1); + } + if ((index = if_nametoindex(ifname)) == 0) { + /* i/f name not found */ + perror("mcast_set_if: ERROR, if_nametoindex"); + errno = ENXIO; + return(-1); + } +#else + index = 0; +#endif /* OS */ + if ((err = setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_IF, + (char*)&index, sizeof(index))) < 0) { + int e = errno; + perror("mcast_set_if: ERROR, setsockopt(IP_MULTICAST_IF)"); + errno = e; + return(-1); + } + return (err); + } +#endif + default: + PRINT_ERR((mcl_stderr, + "mcast_set_if: ERROR, unsupported address family %d\n", af)) +#ifndef WIN32 + errno = EPROTONOSUPPORT; +#endif // !WIN32 + return(-1); + } +} + + +/** + * Set the TTL (with IPv4) or Hop Count (IPv6). + * => See header file for more informations. + */ +INT32 +mcast_set_ttl (MCL_SOCKET sockfd, + INT32 af, + INT32 val) +{ + INT32 err; + + switch (af) { + case AF_INET: { +#ifdef WIN32 + UINT32 ttl; +#else + /* solaris seems to care about the int/char type, not linux! */ + UINT8 ttl; +#endif + + ttl = val; + if ((err = setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, + (char*)&ttl, sizeof(ttl))) < 0) { + perror("mcast_set_ttl: ERROR, setsockopt(TTL)"); + } + break; + } +#ifdef INET6 + case AF_INET6: { + INT32 hops; + hops = val; + if ((err = setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, + (char*)&hops, sizeof(hops))) < 0) { + perror("mcast_set_ttl: ERROR, setsockopt(HOPS)"); + } + break; + } +#endif + default: + PRINT_ERR((mcl_stderr, + "mcast_set_ttl: ERROR, unsupported address family %d\n", af)) +#ifndef WIN32 + errno = EPROTONOSUPPORT; +#endif // !WIN32 + return(-1); + } + return err; +} + + +/** + * Set/unset the loopback mode for multicast traffic. + * => See header file for more informations. + */ +INT32 +mcast_set_loop (MCL_SOCKET sockfd, + INT32 af, + INT32 onoff) +{ + switch (af) { + case AF_INET: { + UINT8 flag; + flag = onoff; + return(setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_LOOP, + (char*)&flag, sizeof(flag))); + } +#ifdef INET6 + case AF_INET6: { + UINT32 flag; + flag = onoff; + return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, + (char*)&flag, sizeof(flag))); + } +#endif + default: + PRINT_ERR((mcl_stderr, + "mcast_set_loop: ERROR, unsupported address family %d\n", af)) +#ifndef WIN32 + errno = EPROTONOSUPPORT; +#endif // !WIN32 + return(-1); + } +} + + +/** + * Join a multicast group. + * => See header file for more informations. + */ +INT32 +mcast_join (MCL_SOCKET sockfd, + const sockaddr *sa, + mcl_addr *ifaddr, + const char *ifname) +{ + INT32 err; // return code + + switch (sa->sa_family) { + case AF_INET: { + struct ip_mreq mreq; + struct sockaddr_in sin; // used if ifaddr is provided +#ifndef WIN32 /* SIOCGIFADDR not defined in WinSock2? */ + struct ifreq ifreq; +#endif /* OS */ + + memcpy(&mreq.imr_multiaddr, + &((struct sockaddr_in *) sa)->sin_addr, + sizeof(struct in_addr)); +#ifndef WIN32 + if (ifname != NULL) { + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) { + PRINT_ERR((mcl_stderr, + "mcast_join: ERROR, SIOCGIFADDR failed\n")) + return(-1); + } + memcpy(&mreq.imr_interface, + &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr, + sizeof(struct in_addr)); + } else +#endif /* OS */ + if (ifaddr != NULL) { + if (ifaddr->is_ipv4_addr() == false) { + PRINT_ERR((mcl_stderr, + "mcast_join: ERROR, ifaddr is IPv6 whereas the declared address family is IPv4!\n")) + errno = EINVAL; + return(-1); + } + ifaddr->get_addr_struct(&sin); + memcpy(&mreq.imr_interface, + &((struct sockaddr_in*)&sin)->sin_addr, + sizeof(struct in_addr)); + } else { + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + } + if ((err = setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, + (char*)&mreq, sizeof(mreq))) < 0) { +#ifndef WIN32 + perror("mcast_join: IP_ADD_MEMBERSHIP:"); +#endif + PRINT_ERR((mcl_stderr, + "mcast_join: ERROR, IP_ADD_MEMBERSHIP failed\n")) + } + return err; + } + +#ifdef INET6 + case AF_INET6: { + struct ipv6_mreq mreq6; + + memcpy(&mreq6.ipv6mr_multiaddr, + &((struct sockaddr_in6 *) sa)->sin6_addr, + sizeof(struct in6_addr)); +#ifndef WIN32 + if (ifname != NULL) { + if ((mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) { + errno = ENXIO; /* i/f name not found */ + return(-1); + } + } else { + mreq6.ipv6mr_interface = 0; + } +#else /* WIN32 */ + mreq6.ipv6mr_interface = 0; +#endif /* OS */ + +#ifdef FREEBSD + err = setsockopt(sockfd, IPPROTO_IPV6, IPV6_JOIN_GROUP, + (char*)&mreq6, sizeof(mreq6)); +#else + err = setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, + (char*)&mreq6, sizeof(mreq6)); +#endif /* OS */ + if (err < 0) { +#ifndef WIN32 + perror("mcast_join: IPV6_ADD_MEMBERSHIP:"); +#endif + PRINT_ERR((mcl_stderr, + "mcast_join: ERROR, IPV6_ADD_MEMBERSHIP failed\n")) + } + return err; + } +#endif /* INET6 */ + + default: + PRINT_ERR((mcl_stderr, + "mcast_join: ERROR, unsupported address family %d\n", + sa->sa_family)) +#ifndef WIN32 + errno = EPROTONOSUPPORT; +#endif // !WIN32 + return(-1); + } +} + + +/** + * Leave a multicast group. + * => See header file for more informations. + */ +INT32 +mcast_leave (MCL_SOCKET sockfd, + const sockaddr *sa, + mcl_addr *ifaddr, + const char *ifname) +{ + switch (sa->sa_family) { + case AF_INET: { + struct ip_mreq mreq; + struct sockaddr_in sin; // used if ifaddr is provided +#ifndef WIN32 /* SIOCGIFADDR not defined in WinSock2? */ + struct ifreq ifreq; +#endif /* OS */ + + memcpy(&mreq.imr_multiaddr, + &((struct sockaddr_in *) sa)->sin_addr, + sizeof(struct in_addr)); +#ifndef WIN32 + if (ifname != NULL) { + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) { + return(-1); + } + memcpy(&mreq.imr_interface, + &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr, + sizeof(struct in_addr)); + } else +#endif /* OS */ + if (ifaddr != NULL) { + if (ifaddr->is_ipv4_addr() == false) { + PRINT_ERR((mcl_stderr, + "mcast_leave: ERROR, ifaddr is IPv6 whereas the declared address family is IPv4!\n")) + errno = EINVAL; + return(-1); + } + ifaddr->get_addr_struct(&sin); + memcpy(&mreq.imr_interface, + &((struct sockaddr_in*)&sin)->sin_addr, + sizeof(struct in_addr)); + } else + mreq.imr_interface.s_addr = htonl(INADDR_ANY); + return(setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, + (char*)&mreq, sizeof(mreq))); + } + +#ifdef INET6 + case AF_INET6: { + struct ipv6_mreq mreq6; + + memcpy(&mreq6.ipv6mr_multiaddr, + &((struct sockaddr_in6 *) sa)->sin6_addr, + sizeof(struct in6_addr)); +#ifndef WIN32 + if (ifname != NULL) { + if ( (mreq6.ipv6mr_interface = if_nametoindex(ifname)) == 0) { + errno = ENXIO; /* i/f name not found */ + return(-1); + } + } else { + mreq6.ipv6mr_interface = 0; + } +#else /* WIN32 */ + mreq6.ipv6mr_interface = 0; +#endif /* OS */ + +#ifdef FREEBSD + return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_LEAVE_GROUP, + (char*)&mreq6, sizeof(mreq6))); +#else + return(setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, + (char*)&mreq6, sizeof(mreq6))); +#endif /* OS */ + } +#endif /* INET6 */ + + default: + PRINT_ERR((mcl_stderr, + "mcast_leave: ERROR, unsupported address family %d\n", + sa->sa_family)) +#ifndef WIN32 + errno = EPROTONOSUPPORT; +#endif // !WIN32 + return(-1); + } +} + + +#ifdef SSM +/** + * Join a multicast group in SSM mode. + * => See header file for more informations. + */ +INT32 +ssm_mcast_join (MCL_SOCKET sockfd, + const sockaddr *sa, + const sockaddr *src_sa, + mcl_addr *ifaddr, + const char *ifname, + INT32 verbosity) +{ + INT32 err; // return code + + ASSERT(src_sa != NULL); + + if (verbosity >= 4) { + mcl_addr tmp_sa; + mcl_addr tmp_src_sa; + + tmp_sa.set_addr_struct(sa); + tmp_src_sa.set_addr_struct(src_sa); + /* get_addr_string uses a static buf, so split the PRINT_OUT */ + PRINT_OUT((mcl_stdout, + "ssm_mcast_join: sa=%s, ", + tmp_sa.get_addr_string())) + PRINT_OUT((mcl_stdout, + "src=%s, ", + tmp_src_sa.get_addr_string())) + PRINT_OUT((mcl_stdout, + "ifaddr=%s, ifname=%s\n", + (ifaddr != NULL) ? ifaddr->get_addr_string() : "null", + (ifname != NULL) ? ifname : "null")) + } + switch (sa->sa_family) { + case AF_INET: { + struct ip_mreq_source mreq_s; // for IGMPv3 SSM join + struct sockaddr_in sin; // used if ifaddr is provided +#ifndef WIN32 /* SIOCGIFADDR not defined in WinSock2? */ + struct ifreq ifreq; +#endif /* OS */ + +#ifdef DEBUG + /* sanity checks */ + if (((ifaddr != NULL) && (ifaddr->is_ipv4_addr() == false)) || + (src_sa->sa_family != AF_INET)) { + PRINT_ERR((mcl_stderr, + "ssm_mcast_join: ERROR, ifaddr or src_addr is IPv6 whereas the declared address family is IPv4!\n")) + errno = EINVAL; + return(-1); + } +#endif /* DEBUG */ + memcpy(&mreq_s.imr_multiaddr, + &((struct sockaddr_in *) sa)->sin_addr, + sizeof(struct in_addr)); +#ifndef WIN32 + if (ifname != NULL) { + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) { + PRINT_ERR((mcl_stderr, + "ssm_mcast_join: ERROR, SIOCGIFADDR failed\n")) + return(-1); + } + memcpy(&mreq_s.imr_interface, + &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr, + sizeof(struct in_addr)); + } else +#endif /* OS */ + if (ifaddr != NULL) { + ifaddr->get_addr_struct(&sin); + memcpy(&mreq_s.imr_interface, + &((struct sockaddr_in*)&sin)->sin_addr, + sizeof(struct in_addr)); + } else { + mreq_s.imr_interface.s_addr = htonl(INADDR_ANY); + } + memcpy(&mreq_s.imr_sourceaddr, + &((struct sockaddr_in *) src_sa)->sin_addr, + sizeof(struct in_addr)); + if ((err = setsockopt(sockfd, IPPROTO_IP, IP_ADD_SOURCE_MEMBERSHIP, + (char*)&mreq_s, sizeof(mreq_s))) < 0) { +#ifndef WIN32 + perror("ssm_mcast_join: IP_ADD_SOURCE_MEMBERSHIP:"); +#endif + PRINT_ERR((mcl_stderr, + "ssm_mcast_join: ERROR, IP_ADD_SOURCE_MEMBERSHIP failed\n")) + } + return err; + } + +#ifdef INET6 +#ifdef LINUX // only available on Linux in this release! + case AF_INET6: { + struct group_source_req gs_req; // for MLDv2 SSM join + +#ifdef DEBUG + /* sanity checks */ + if (src_sa->sa_family != AF_INET6) { + PRINT_ERR((mcl_stderr, + "ssm_mcast_join: ERROR, src_addr is IPv4 whereas the declared address family is IPv6!\n")) + errno = EINVAL; + return(-1); + } +#endif /* DEBUG */ + memcpy(&gs_req.gsr_group, (void*)sa, + sizeof(struct sockaddr_in6)); +#ifndef WIN32 + if (ifname != NULL) { + if ((gs_req.gsr_interface = if_nametoindex(ifname)) == 0) { + errno = ENXIO; /* i/f name not found */ + return(-1); + } + } else { + gs_req.gsr_interface = 0; + } +#else /* WIN32 */ + gs_req.gsr_interface = 0; +#endif /* OS */ + memcpy(&gs_req.gsr_source, (void*)src_sa, + sizeof(struct sockaddr_in6)); + if ((err = setsockopt(sockfd, IPPROTO_IPV6, MCAST_JOIN_SOURCE_GROUP, + (char*)&gs_req, sizeof(gs_req))) < 0) { +#ifndef WIN32 + perror("ssm_mcast_join: MCAST_JOIN_SOURCE_GROUP for IPv6:"); +#endif + PRINT_ERR((mcl_stderr, + "ssm_mcast_join: ERROR, MCAST_JOIN_SOURCE_GROUP for IPv6failed\n")) + } + return err; + } +#endif /* LINUX */ +#endif /* INET6 */ + + default: + PRINT_ERR((mcl_stderr, + "ssm_mcast_join: ERROR, unsupported address family %d\n", + sa->sa_family)) +#ifndef WIN32 + errno = EPROTONOSUPPORT; +#endif // !WIN32 + return(-1); + } +} + + +/** + * Leave a multicast group in SSM mode. + * IPv4 and IPv6 compatible. + * @param sockfd socket file descriptor + * @param sa socket address + * @param ifaddr interface address. Only used for IPv4. + * @param ifname interface name (e.g. eth0). For IPv4 or IPv6. + * @return + */ +extern INT32 +ssm_mcast_leave (MCL_SOCKET sockfd, + const sockaddr *sa, + const sockaddr *src_sa, + mcl_addr *ifaddr, + const char *ifname, + INT32 verbosity) +{ + INT32 err; // return code + + if (verbosity >= 4) { + mcl_addr tmp_sa; + mcl_addr tmp_src_sa; + + tmp_sa.set_addr_struct(sa); + tmp_src_sa.set_addr_struct(src_sa); + /* get_addr_string uses a static buf, so split the PRINT_OUT */ + PRINT_OUT((mcl_stdout, + "ssm_mcast_leave: sa=%s, ", + tmp_sa.get_addr_string())) + PRINT_OUT((mcl_stdout, + "src=%s, ", + tmp_src_sa.get_addr_string())) + PRINT_OUT((mcl_stdout, + "ifaddr=%s, ifname=%s\n", + (ifaddr != NULL) ? ifaddr->get_addr_string() : "null", + (ifname != NULL) ? ifname : "null")) + } + switch (sa->sa_family) { + case AF_INET: { + struct ip_mreq_source mreq_s; // for IGMPv3 SSM join + struct sockaddr_in sin; // used if ifaddr is provided +#ifndef WIN32 /* SIOCGIFADDR not defined in WinSock2? */ + struct ifreq ifreq; +#endif /* OS */ + + memcpy(&mreq_s.imr_multiaddr, + &((struct sockaddr_in *) sa)->sin_addr, + sizeof(struct in_addr)); +#ifndef WIN32 + if (ifname != NULL) { + strncpy(ifreq.ifr_name, ifname, IFNAMSIZ); + if (ioctl(sockfd, SIOCGIFADDR, &ifreq) < 0) { + return(-1); + } + memcpy(&mreq_s.imr_interface, + &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr, + sizeof(struct in_addr)); + } else +#endif /* OS */ + if (ifaddr != NULL) { + if (ifaddr->is_ipv4_addr() == false) { + PRINT_ERR((mcl_stderr, + "ssm_mcast_leave: ERROR, ifaddr is IPv6 whereas the declared address family is IPv4!\n")) + errno = EINVAL; + return(-1); + } + ifaddr->get_addr_struct(&sin); + memcpy(&mreq_s.imr_interface, + &((struct sockaddr_in*)&sin)->sin_addr, + sizeof(struct in_addr)); + } else + mreq_s.imr_interface.s_addr = htonl(INADDR_ANY); + + memcpy(&mreq_s.imr_sourceaddr, + &((struct sockaddr_in *) src_sa)->sin_addr, + sizeof(struct in_addr)); + if ((err = setsockopt(sockfd, IPPROTO_IP, + IP_DROP_SOURCE_MEMBERSHIP, + (char*)&mreq_s, sizeof(mreq_s))) < 0) { +#ifndef WIN32 + perror("ssm_mcast_leave: IP_DROP_SOURCE_MEMBERSHIP for IPv4:"); +#endif + PRINT_ERR((mcl_stderr, + "ssm_mcast_leave: ERROR, IP_DROP_SOURCE_MEMBERSHIP for IPv4 failed\n")) + } + return err; + } + +#ifdef INET6 +#ifdef LINUX // only available on Linux in this release! + case AF_INET6: { + struct group_source_req gs_req; // for MLDv2 SSM leave + + memcpy(&gs_req.gsr_group, (void*)sa, + sizeof(struct sockaddr_in6)); +#ifndef WIN32 + if (ifname != NULL) { + if ( (gs_req.gsr_interface = if_nametoindex(ifname)) == 0) { + errno = ENXIO; /* i/f name not found */ + return(-1); + } + } else { + gs_req.gsr_interface = 0; + } +#else /* WIN32 */ + gs_req.gsr_interface = 0; +#endif /* OS */ + memcpy(&gs_req.gsr_source, (void*) src_sa, + sizeof(struct sockaddr_in6)); + if ((err = setsockopt(sockfd, IPPROTO_IPV6, MCAST_LEAVE_SOURCE_GROUP, + (char*)&gs_req, sizeof(gs_req))) < 0) { +#ifndef WIN32 + perror("ssm_mcast_leave: MCAST_LEAVE_SOURCE_GROUP for IPv6:"); +#endif + PRINT_ERR((mcl_stderr, + "ssm_mcast_leave: ERROR, MCAST_LEAVE_SOURCE_GROUP for IPv6failed\n")) + } + return err; + } +#endif /* LINUX */ +#endif /* INET6 */ + + default: + PRINT_ERR((mcl_stderr, + "ssm_mcast_leave: ERROR, unsupported address family %d\n", + sa->sa_family)) +#ifndef WIN32 + errno = EPROTONOSUPPORT; +#endif // !WIN32 + return(-1); + } +} +#endif /* SSM */ + diff --git a/src/common/mcl_socket_lib.h b/src/common/mcl_socket_lib.h new file mode 100644 index 0000000..509b64b --- /dev/null +++ b/src/common/mcl_socket_lib.h @@ -0,0 +1,139 @@ +/* $Id: mcl_socket_lib.h,v 1.9 2005/05/24 15:43:23 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/******************************************************************************/ +/* + * Code derived from Richard Stevens's book + * "UNIX Network Programming, Volume 1, Second Edition: "Networking + * APIs: Sockets and XTI", Prentice Hall, 1998, ISBN 0-13-490012-X. + * Available at URL: http://www.kohala.com/start/unpv12e.html + */ + + +/** + * Set the multicast interface where to send or receive multicast traffic. + * IPv4 and IPv6 compatible. + * @param sockfd socket file descriptor + * @param af address familly + * @param ifaddr interface address. Only used for IPv4. + * @param ifname interface name (e.g. eth0). For IPv4 or IPv6. + * @param verbosity level of verbosity needed + * @return + */ +extern INT32 mcast_set_if (MCL_SOCKET sockfd, + INT32 af, + mcl_addr *ifaddr, + const char *ifname, + INT32 verbosity); + + +/** + * Set the TTL (with IPv4) or Hop Count (IPv6). + * IPv4 and IPv6 compatible. + * @param sockfd socket file descriptor + * @param af address familly + * @param val new TTL value to set + * @return + */ +extern INT32 mcast_set_ttl (MCL_SOCKET sockfd, + INT32 af, + INT32 val); + + +/** + * Set/unset the loopback mode for multicast traffic. + * IPv4 and IPv6 compatible. + * @param sockfd socket file descriptor + * @param af address familly + * @param + * @return + */ +extern INT32 mcast_set_loop (MCL_SOCKET sockfd, + INT32 af, + INT32 onoff); + + +/** + * Join a multicast group. + * IPv4 and IPv6 compatible. + * @param sockfd socket file descriptor + * @param sa mcast group address to join + * @param src_sa source address in SSM mode. SSM join mode is + * used if and only if src_sa != NULL. + * @param ifaddr interface address. Only used for IPv4. + * @param ifname interface name (e.g. eth0). For IPv4 or IPv6. + * @return + */ +extern INT32 mcast_join (MCL_SOCKET sockfd, + const sockaddr *sa, + mcl_addr *ifaddr, + const char *ifname); + +/** + * Leave a multicast group. + * IPv4 and IPv6 compatible. + * @param sockfd socket file descriptor + * @param sa socket address + * @param ifaddr interface address. Only used for IPv4. + * @param ifname interface name (e.g. eth0). For IPv4 or IPv6. + * @return + */ +extern INT32 mcast_leave (MCL_SOCKET sockfd, + const sockaddr *sa, + mcl_addr *ifaddr, + const char *ifname); + +#ifdef SSM +/** + * Join a multicast group in SSM mode. + * IPv4 and IPv6 compatible. + * @param sockfd socket file descriptor + * @param sa mcast group address to join + * @param src_sa source address in SSM mode. + * @param ifaddr interface address. Only used for IPv4. + * @param ifname interface name (e.g. eth0). For IPv4 or IPv6. + * @return + */ +extern INT32 ssm_mcast_join (MCL_SOCKET sockfd, + const sockaddr *sa, + const sockaddr *src_sa, + mcl_addr *ifaddr, + const char *ifname, + INT32 verbosity); + +/** + * Leave a multicast group in SSM mode. + * IPv4 and IPv6 compatible. + * @param sockfd socket file descriptor + * @param sa socket address + * @param ifaddr interface address. Only used for IPv4. + * @param ifname interface name (e.g. eth0). For IPv4 or IPv6. + * @return + */ +extern INT32 ssm_mcast_leave (MCL_SOCKET sockfd, + const sockaddr *sa, + const sockaddr *src_sa, + mcl_addr *ifaddr, + const char *ifname, + INT32 verbosity); +#endif + diff --git a/src/common/mcl_types.h b/src/common/mcl_types.h new file mode 100644 index 0000000..ab00e7d --- /dev/null +++ b/src/common/mcl_types.h @@ -0,0 +1,52 @@ +/* $Id: mcl_types.h,v 1.2 2005/04/08 15:23:31 moi Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_TYPES_H +#define MCL_TYPES_H + +/* + * types + */ +#ifndef UINT32 +#define INT8 char +#define INT16 short +#define UINT8 unsigned char +#define UINT16 unsigned short +#if defined(__LP64__) || (__WORDSIZE == 64) /* 64 bit architectures */ +#define INT32 long +#define UINT32 unsigned long +#else /* 32 bit architectures */ +#define INT32 int // int creates less compilations pbs than long +#define UINT32 unsigned int // int creates less compilations pbs than long +#endif /* 32/64 architectures */ +#endif /* !UINT32 */ + +#if defined(WIN32) +#define INT64 LONGLONG +#define UINT64 ULONGLONG +#else /* UNIX */ +#define INT64 long long +#define UINT64 unsigned long long +#endif /* OS */ + +#define TOI_t UINT32 + +#endif /* MCL_TYPES_H */ diff --git a/src/common/mcl_version.h b/src/common/mcl_version.h new file mode 100644 index 0000000..6b7c786 --- /dev/null +++ b/src/common/mcl_version.h @@ -0,0 +1,22 @@ +/* $Id: mcl_version.h,v 1.24 2005/03/18 12:06:20 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#define MCLv3_VERSION " Release 2.99.6-pre, May 25th, 2005\n" diff --git a/src/common/rse_fec.cpp b/src/common/rse_fec.cpp new file mode 100644 index 0000000..60aba63 --- /dev/null +++ b/src/common/rse_fec.cpp @@ -0,0 +1,970 @@ +/* $Id: rse_fec.cpp,v 1.2 2004/05/11 10:49:49 roca Exp $ */ +/* + * fec.c -- forward error correction based on Vandermonde matrices + * 980624 + * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it) + * + * Portions derived from code by Phil Karn (karn@ka9q.ampr.org), + * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari + * Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +#define FEC /* VR: added */ + +#ifdef FEC + + +/* + * The following parameter defines how many bits are used for + * field elements. The code supports any value from 2 to 16 + * but fastest operation is achieved with 8 bit elements + * This is the only parameter you may want to change. + */ +#ifndef GF_BITS +#define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */ +#endif + +#include +#include +#include + +#ifndef WIN32 +#include /* VR: added */ +#endif + +#include /* VR: added */ +#define MCL_DEBUG_NO_PRINT_DU_FUNC /* to solve a compiling pb in mcl_debug.h */ +#include "../common/mcl_debug.h" /* VR: added */ +#undef MCL_DEBUG_NO_PRINT_DU_FUNC + +/* + * compatibility stuff + */ +#if (defined(MSDOS) || defined(WIN32)) /* but also for others, e.g. sun... */ +#define NEED_BCOPY +#define bcmp(a,b,n) memcmp(a,b,n) +#endif + +#ifdef NEED_BCOPY +#define bcopy(s, d, siz) memcpy((d), (s), (siz)) +#define bzero(d, siz) memset((d), '\0', (siz)) +#endif + +#ifndef UINT32 + #define UINT32 unsigned long +#endif + +/* + * stuff used for testing purposes only + */ + +#ifdef TICK /* VR: avoid a warning under Solaris */ +#undef TICK +#endif + +#ifdef TEST +#define DEB(x) +#define DDB(x) x +#define DEBUG 4 /* minimal debugging */ +#if (defined(MSDOS) || defined(WIN32)) +#include +struct timeval { + unsigned long ticks; +}; +#define gettimeofday(x, dummy) { (x)->ticks = clock() ; } +#define DIFF_T(a,b) (1+ 1000000*(a.ticks - b.ticks) / CLOCKS_PER_SEC ) +typedef unsigned long UINT32 ; +typedef unsigned short u_short ; +#else /* typically, unix systems */ +#include +#define DIFF_T(a,b) \ + (1+ 1000000*(a.tv_sec - b.tv_sec) + (a.tv_usec - b.tv_usec) ) +#endif + +#define TICK(t) \ + {struct timeval x ; \ + gettimeofday(&x, NULL) ; \ + t = x.tv_usec + 1000000* (x.tv_sec & 0xff ) ; \ + } +#define TOCK(t) \ + { UINT32 t1 ; TICK(t1) ; \ + if (t1 < t) t = 256000000 + t1 - t ; \ + else t = t1 - t ; \ + if (t == 0) t = 1 ;} + +UINT32 ticks[10]; /* vars for timekeeping */ +#else +#define DEB(x) +#define DDB(x) +#define TICK(x) +#define TOCK(x) +#endif /* TEST */ + +/* + * You should not need to change anything beyond this point. + * The first part of the file implements linear algebra in GF. + * + * gf is the type used to store an element of the Galois Field. + * Must constain at least GF_BITS bits. + * + * Note: unsigned char will work up to GF(256) but int seems to run + * faster on the Pentium. We use int whenever have to deal with an + * index, since they are generally faster. + */ +#if (GF_BITS < 2 && GF_BITS >16) +#error "GF_BITS must be 2 .. 16" +#endif +#if (GF_BITS <= 8) +typedef unsigned char gf; +#else +typedef unsigned short gf; +#endif + +#define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */ + +/* + * Primitive polynomials - see Lin & Costello, Appendix A, + * and Lee & Messerschmitt, p. 453. + */ +static char *allPp[] = { /* GF_BITS polynomial */ + NULL, /* 0 no code */ + NULL, /* 1 no code */ + "111", /* 2 1+x+x^2 */ + "1101", /* 3 1+x+x^3 */ + "11001", /* 4 1+x+x^4 */ + "101001", /* 5 1+x^2+x^5 */ + "1100001", /* 6 1+x+x^6 */ + "10010001", /* 7 1 + x^3 + x^7 */ + "101110001", /* 8 1+x^2+x^3+x^4+x^8 */ + "1000100001", /* 9 1+x^4+x^9 */ + "10010000001", /* 10 1+x^3+x^10 */ + "101000000001", /* 11 1+x^2+x^11 */ + "1100101000001", /* 12 1+x+x^4+x^6+x^12 */ + "11011000000001", /* 13 1+x+x^3+x^4+x^13 */ + "110000100010001", /* 14 1+x+x^6+x^10+x^14 */ + "1100000000000001", /* 15 1+x+x^15 */ + "11010000000010001" /* 16 1+x+x^3+x^12+x^16 */ +}; + + +/* + * To speed up computations, we have tables for logarithm, exponent + * and inverse of a number. If GF_BITS <= 8, we use a table for + * multiplication as well (it takes 64K, no big deal even on a PDA, + * especially because it can be pre-initialized an put into a ROM!), + * otherwhise we use a table of logarithms. + * In any case the macro gf_mul(x,y) takes care of multiplications. + */ + +static gf gf_exp[2*GF_SIZE]; /* index->poly form conversion table */ +static int gf_log[GF_SIZE + 1]; /* Poly->index form conversion table */ +static gf inverse[GF_SIZE+1]; /* inverse of field elem. */ + /* inv[\alpha**i]=\alpha**(GF_SIZE-i-1) */ + +/* + * modnn(x) computes x % GF_SIZE, where GF_SIZE is 2**GF_BITS - 1, + * without a slow divide. + */ +static gf +modnn(int x) +{ + while (x >= GF_SIZE) { + x -= GF_SIZE; + x = (x >> GF_BITS) + (x & GF_SIZE); + } + return x; +} + +#define SWAP(a,b,t) {t tmp; tmp=a; a=b; b=tmp;} + +/* + * gf_mul(x,y) multiplies two numbers. If GF_BITS<=8, it is much + * faster to use a multiplication table. + * + * USE_GF_MULC, GF_MULC0(c) and GF_ADDMULC(x) can be used when multiplying + * many numbers by the same constant. In this case the first + * call sets the constant, and others perform the multiplications. + * A value related to the multiplication is held in a local variable + * declared with USE_GF_MULC . See usage in addmul1(). + */ +#if (GF_BITS <= 8) +static gf gf_mul_table[GF_SIZE + 1][GF_SIZE + 1]; + +#define gf_mul(x,y) gf_mul_table[x][y] + +#define USE_GF_MULC register gf * __gf_mulc_ +#define GF_MULC0(c) __gf_mulc_ = gf_mul_table[c] +#define GF_ADDMULC(dst, x) dst ^= __gf_mulc_[x] + +static void +init_mul_table() +{ + int i, j; + for (i=0; i< GF_SIZE+1; i++) + for (j=0; j< GF_SIZE+1; j++) + gf_mul_table[i][j] = gf_exp[modnn(gf_log[i] + gf_log[j]) ] ; + + for (j=0; j< GF_SIZE+1; j++) + gf_mul_table[0][j] = gf_mul_table[j][0] = 0; +} +#else /* GF_BITS > 8 */ +static inline gf +gf_mul(x,y) +{ + if ( (x) == 0 || (y)==0 ) return 0; + + return gf_exp[gf_log[x] + gf_log[y] ] ; +} +#define init_mul_table() + +#define USE_GF_MULC register gf * __gf_mulc_ +#define GF_MULC0(c) __gf_mulc_ = &gf_exp[ gf_log[c] ] +#define GF_ADDMULC(dst, x) { if (x) dst ^= __gf_mulc_[ gf_log[x] ] ; } +#endif + +/* + * Generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m] + * Lookup tables: + * index->polynomial form gf_exp[] contains j= \alpha^i; + * polynomial form -> index form gf_log[ j = \alpha^i ] = i + * \alpha=x is the primitive element of GF(2^m) + * + * For efficiency, gf_exp[] has size 2*GF_SIZE, so that a simple + * multiplication of two numbers can be resolved without calling modnn + */ + +/* + * i use malloc so many times, it is easier to put checks all in + * one place. + */ +static void * +my_malloc(int sz, char *err_string) +{ + void *p = malloc( sz ); + if (p == NULL) { + PRINT_ERR((mcl_stderr, "-- malloc failure allocation %s\n", err_string)) + exit(1) ; + } + return p ; +} + +#define NEW_GF_MATRIX(rows, cols) \ + (gf *)my_malloc(rows * cols * sizeof(gf), " ## __LINE__ ## " ) + +/* + * initialize the data structures used for computations in GF. + */ +static void +generate_gf(void) +{ + int i; + gf mask; + char *Pp = allPp[GF_BITS] ; + + mask = 1; /* x ** 0 = 1 */ + gf_exp[GF_BITS] = 0; /* will be updated at the end of the 1st loop */ + /* + * first, generate the (polynomial representation of) powers of \alpha, + * which are stored in gf_exp[i] = \alpha ** i . + * At the same time build gf_log[gf_exp[i]] = i . + * The first GF_BITS powers are simply bits shifted to the left. + */ + for (i = 0; i < GF_BITS; i++, mask <<= 1 ) { + gf_exp[i] = mask; + gf_log[gf_exp[i]] = i; + /* + * If Pp[i] == 1 then \alpha ** i occurs in poly-repr + * gf_exp[GF_BITS] = \alpha ** GF_BITS + */ + if ( Pp[i] == '1' ) + gf_exp[GF_BITS] ^= mask; + } + /* + * now gf_exp[GF_BITS] = \alpha ** GF_BITS is complete, so can als + * compute its inverse. + */ + gf_log[gf_exp[GF_BITS]] = GF_BITS; + /* + * Poly-repr of \alpha ** (i+1) is given by poly-repr of + * \alpha ** i shifted left one-bit and accounting for any + * \alpha ** GF_BITS term that may occur when poly-repr of + * \alpha ** i is shifted. + */ + mask = 1 << (GF_BITS - 1 ) ; + for (i = GF_BITS + 1; i < GF_SIZE; i++) { + if (gf_exp[i - 1] >= mask) + gf_exp[i] = gf_exp[GF_BITS] ^ ((gf_exp[i - 1] ^ mask) << 1); + else + gf_exp[i] = gf_exp[i - 1] << 1; + gf_log[gf_exp[i]] = i; + } + /* + * log(0) is not defined, so use a special value + */ + gf_log[0] = GF_SIZE ; + /* set the extended gf_exp values for fast multiply */ + for (i = 0 ; i < GF_SIZE ; i++) + gf_exp[i + GF_SIZE] = gf_exp[i] ; + + /* + * again special cases. 0 has no inverse. This used to + * be initialized to GF_SIZE, but it should make no difference + * since noone is supposed to read from here. + */ + inverse[0] = 0 ; + inverse[1] = 1; + for (i=2; i<=GF_SIZE; i++) + inverse[i] = gf_exp[GF_SIZE-gf_log[i]]; +} + +/* + * Various linear algebra operations that i use often. + */ + +/* + * addmul() computes dst[] = dst[] + c * src[] + * This is used often, so better optimize it! Currently the loop is + * unrolled 16 times, a good value for 486 and pentium-class machines. + * The case c=0 is also optimized, whereas c=1 is not. These + * calls are unfrequent in my typical apps so I did not bother. + * + * Note that gcc on + */ +#define addmul(dst, src, c, sz) \ + if (c != 0) addmul1(dst, src, c, sz) + +#define UNROLL 16 /* 1, 4, 8, 16 */ +static void +addmul1(gf *dst1, gf *src1, gf c, int sz) +{ + USE_GF_MULC ; + register gf *dst = dst1, *src = src1 ; + gf *lim = &dst[sz - UNROLL + 1] ; + + GF_MULC0(c) ; + +#if (UNROLL > 1) /* unrolling by 8/16 is quite effective on the pentium */ + for (; dst < lim ; dst += UNROLL, src += UNROLL ) { + GF_ADDMULC( dst[0] , src[0] ); + GF_ADDMULC( dst[1] , src[1] ); + GF_ADDMULC( dst[2] , src[2] ); + GF_ADDMULC( dst[3] , src[3] ); +#if (UNROLL > 4) + GF_ADDMULC( dst[4] , src[4] ); + GF_ADDMULC( dst[5] , src[5] ); + GF_ADDMULC( dst[6] , src[6] ); + GF_ADDMULC( dst[7] , src[7] ); +#endif +#if (UNROLL > 8) + GF_ADDMULC( dst[8] , src[8] ); + GF_ADDMULC( dst[9] , src[9] ); + GF_ADDMULC( dst[10] , src[10] ); + GF_ADDMULC( dst[11] , src[11] ); + GF_ADDMULC( dst[12] , src[12] ); + GF_ADDMULC( dst[13] , src[13] ); + GF_ADDMULC( dst[14] , src[14] ); + GF_ADDMULC( dst[15] , src[15] ); +#endif + } +#endif + lim += UNROLL - 1 ; + for (; dst < lim; dst++, src++ ) /* final components */ + GF_ADDMULC( *dst , *src ); +} + +/* + * computes C = AB where A is n*k, B is k*m, C is n*m + */ +static void +matmul(gf *a, gf *b, gf *c, int n, int k, int m) +{ + int row, col, i ; + + for (row = 0; row < n ; row++) { + for (col = 0; col < m ; col++) { + gf *pa = &a[ row * k ]; + gf *pb = &b[ col ]; + gf acc = 0 ; + for (i = 0; i < k ; i++, pa++, pb += m ) + acc ^= gf_mul( *pa, *pb ) ; + c[ row * m + col ] = acc ; + } + } +} +#ifdef DEBUG +/* + * returns 1 if the square matrix is identiy + * (only for test) + */ +/* +static int +is_identity(gf *m, int k) +{ + int row, col ; + for (row=0; row 1) { + PRINT_ERR((mcl_stderr, "singular matrix\n")) + goto fail ; + } + } + } + } + if (icol == -1) { + PRINT_ERR((mcl_stderr, "XXX pivot not found!\n")) + goto fail ; + } +found_piv: + ++(ipiv[icol]) ; + /* + * swap rows irow and icol, so afterwards the diagonal + * element will be correct. Rarely done, not worth + * optimizing. + */ + if (irow != icol) { + for (ix = 0 ; ix < k ; ix++ ) { + SWAP( src[irow*k + ix], src[icol*k + ix], gf) ; + } + } + indxr[col] = irow ; + indxc[col] = icol ; + pivot_row = &src[icol*k] ; + c = pivot_row[icol] ; + if (c == 0) { + PRINT_ERR((mcl_stderr, "singular matrix 2\n")) + goto fail ; + } + if (c != 1 ) { /* otherwhise this is a NOP */ + /* + * this is done often , but optimizing is not so + * fruitful, at least in the obvious ways (unrolling) + */ + DEB( pivswaps++ ; ) + c = inverse[ c ] ; + pivot_row[icol] = 1 ; + for (ix = 0 ; ix < k ; ix++ ) + pivot_row[ix] = gf_mul(c, pivot_row[ix] ); + } + /* + * from all rows, remove multiples of the selected row + * to zero the relevant entry (in fact, the entry is not zero + * because we know it must be zero). + * (Here, if we know that the pivot_row is the identity, + * we can optimize the addmul). + */ + id_row[icol] = 1; + if (bcmp(pivot_row, id_row, k*sizeof(gf)) != 0) { + for (p = src, ix = 0 ; ix < k ; ix++, p += k ) { + if (ix != icol) { + c = p[icol] ; + p[icol] = 0 ; + addmul(p, pivot_row, c, k ); + } + } + } + id_row[icol] = 0; + } /* done all columns */ + for (col = k-1 ; col >= 0 ; col-- ) { + if (indxr[col] <0 || indxr[col] >= k) + PRINT_ERR((mcl_stderr, "AARGH, indxr[col] %d\n", indxr[col])) + else if (indxc[col] <0 || indxc[col] >= k) + PRINT_ERR((mcl_stderr, "AARGH, indxc[col] %d\n", indxc[col])) + else + if (indxr[col] != indxc[col] ) { + for (row = 0 ; row < k ; row++ ) { + SWAP( src[row*k + indxr[col]], src[row*k + indxc[col]], gf) ; + } + } + } + error = 0 ; +fail: + free(indxc); + free(indxr); + free(ipiv); + free(id_row); + free(temp_row); + return error ; +} + +/* + * fast code for inverting a vandermonde matrix. + * XXX NOTE: It assumes that the matrix + * is not singular and _IS_ a vandermonde matrix. Only uses + * the second column of the matrix, containing the p_i's. + * + * Algorithm borrowed from "Numerical recipes in C" -- sec.2.8, but + * largely revised for my purposes. + * p = coefficients of the matrix (p_i) + * q = values of the polynomial (known) + */ + +int +invert_vdm(gf *src, int k) +{ + int i, j, row, col ; + gf *b, *c, *p; + gf t, xx ; + + if (k == 1) /* degenerate case, matrix must be p^0 = 1 */ + return 0 ; + /* + * c holds the coefficient of P(x) = Prod (x - p_i), i=0..k-1 + * b holds the coefficient for the matrix inversion + */ + c = NEW_GF_MATRIX(1, k); + b = NEW_GF_MATRIX(1, k); + + p = NEW_GF_MATRIX(1, k); + + for ( j=1, i = 0 ; i < k ; i++, j+=k ) { + c[i] = 0 ; + p[i] = src[j] ; /* p[i] */ + } + /* + * construct coeffs. recursively. We know c[k] = 1 (implicit) + * and start P_0 = x - p_0, then at each stage multiply by + * x - p_i generating P_i = x P_{i-1} - p_i P_{i-1} + * After k steps we are done. + */ + c[k-1] = p[0] ; /* really -p(0), but x = -x in GF(2^m) */ + for (i = 1 ; i < k ; i++ ) { + gf p_i = p[i] ; /* see above comment */ + for (j = k-1 - ( i - 1 ) ; j < k-1 ; j++ ) + c[j] ^= gf_mul( p_i, c[j+1] ) ; + c[k-1] ^= p_i ; + } + + for (row = 0 ; row < k ; row++ ) { + /* + * synthetic division etc. + */ + xx = p[row] ; + t = 1 ; + b[k-1] = 1 ; /* this is in fact c[k] */ + for (i = k-2 ; i >= 0 ; i-- ) { + b[i] = c[i+1] ^ gf_mul(xx, b[i+1]) ; + t = gf_mul(xx, t) ^ b[i] ; + } + for (col = 0 ; col < k ; col++ ) + src[col*k + row] = gf_mul(inverse[t], b[col] ); + } + free(c) ; + free(b) ; + free(p) ; + return 0 ; +} + +static int fec_initialized = 0 ; +/* static */ void /* VR: removed static */ +init_fec() +{ + TICK(ticks[0]); + generate_gf(); + TOCK(ticks[0]); + DDB(PRINT_ERR((mcl_stderr, "generate_gf took %ldus\n", ticks[0]))) + TICK(ticks[0]); + init_mul_table(); + TOCK(ticks[0]); + DDB(PRINT_ERR((mcl_stderr, "init_mul_table took %ldus\n", ticks[0]))) + fec_initialized = 1 ; +} + +/* + * This section contains the proper FEC encoding/decoding routines. + * The encoding matrix is computed starting with a Vandermonde matrix, + * and then transforming it into a systematic matrix. + */ + +#define FEC_MAGIC 0xFECC0DEC + +struct fec_parms { + UINT32 magic ; + int k, n ; /* parameters of the code */ + gf *enc_matrix ; +} ; + + +#define CPLUSPLUS_COMPATIBLE /* VR: added */ +#ifdef CPLUSPLUS_COMPATIBLE +void fec_free(void *p_vp) +#else +void fec_free(struct fec_parms *p) +#endif /* CPLUSPLUS_COMPATIBLE */ +{ +#ifdef CPLUSPLUS_COMPATIBLE + struct fec_parms *p = (struct fec_parms *)p_vp; /* VR */ +#endif /* CPLUSPLUS_COMPATIBLE */ + if (p==NULL || + p->magic != ( ( (FEC_MAGIC ^ p->k) ^ p->n) ^ (int)(p->enc_matrix)) ) { + PRINT_ERR((mcl_stderr, "bad parameters to fec_free\n")) + return ; + } + free(p->enc_matrix); + free(p); +} + +/* + * create a new encoder, returning a descriptor. This contains k,n and + * the encoding matrix. + */ +#if 0 /* VR: changed as it creates problems with C++ compilers */ +struct fec_parms * +#else +void * +#endif +fec_new(int k, int n) +{ + int row, col ; + gf *p, *tmp_m ; + + struct fec_parms *retval ; + + if (fec_initialized == 0) + init_fec(); + + if (k > GF_SIZE + 1 || n > GF_SIZE + 1 || k > n ) { + PRINT_ERR((mcl_stderr, "Invalid parameters k %d n %d GF_SIZE %d\n", + k, n, GF_SIZE )) + return NULL ; + } + retval = (struct fec_parms*)my_malloc(sizeof(struct fec_parms), "new_code"); + retval->k = k ; + retval->n = n ; + retval->enc_matrix = NEW_GF_MATRIX(n, k); + retval->magic = ( ( FEC_MAGIC ^ k) ^ n) ^ (int)(retval->enc_matrix) ; + tmp_m = NEW_GF_MATRIX(n, k); + /* + * fill the matrix with powers of field elements, starting from 0. + * The first row is special, cannot be computed with exp. table. + */ + tmp_m[0] = 1 ; + for (col = 1; col < k ; col++) + tmp_m[col] = 0 ; + for (p = tmp_m + k, row = 0; row < n-1 ; row++, p += k) { + for ( col = 0 ; col < k ; col ++ ) + p[col] = gf_exp[modnn(row*col)]; + } + + /* + * quick code to build systematic matrix: invert the top + * k*k vandermonde matrix, multiply right the bottom n-k rows + * by the inverse, and construct the identity matrix at the top. + */ + TICK(ticks[3]); + invert_vdm(tmp_m, k); /* much faster than invert_mat */ + matmul(tmp_m + k*k, tmp_m, retval->enc_matrix + k*k, n - k, k, k); + /* + * the upper matrix is I so do not bother with a slow multiply + */ + bzero(retval->enc_matrix, k*k*sizeof(gf) ); + for (p = retval->enc_matrix, col = 0 ; col < k ; col++, p += k+1 ) + *p = 1 ; + free(tmp_m); + TOCK(ticks[3]); + + DDB(PRINT_ERR((mcl_stderr, "--- %ld us to build encoding matrix\n", + ticks[3]))) + DEB(pr_matrix(retval->enc_matrix, n, k, "encoding_matrix");) +#if 0 /* VR: changed as it creates problems with C++ compilers */ + return retval ; +#else + return (void*)retval ; +#endif +} + +/* + * fec_encode accepts as input pointers to n data packets of size sz, + * and produces as output a packet pointed to by fec, computed + * with index "index". + */ +/* + * VR: changed for C++ compilers who don't accept diff in parameters... + * Use a definition that matches prototype in fec.h + */ +#define CPLUSPLUS_COMPATIBLE /* VR: added */ +#ifdef CPLUSPLUS_COMPATIBLE +void +fec_encode(void *code_vp, void **src_vp, void *fec_vp, int index, int sz) +#else +void +fec_encode(struct fec_parms *code, gf *src[], gf *fec, int index, int sz) +#endif +{ +#ifdef CPLUSPLUS_COMPATIBLE + struct fec_parms *code = (struct fec_parms*)code_vp;/* VR */ + gf **src = (gf**)src_vp; /* VR */ + gf *fec = (gf*)fec_vp; /* VR */ +#endif /* CPLUSPLUS_COMPATIBLE */ + int i, k = code->k ; + gf *p ; + + if (GF_BITS > 8) + sz /= 2 ; + + if (index < k) + bcopy(src[index], fec, sz*sizeof(gf) ) ; + else if (index < code->n) { + p = &(code->enc_matrix[index*k] ); + bzero(fec, sz*sizeof(gf)); + for (i = 0; i < k ; i++) + addmul(fec, src[i], p[i], sz ) ; + } else + PRINT_ERR((mcl_stderr, "Invalid index %d (max %d)\n", + index, code->n - 1 )) +} + +/* + * shuffle move src packets in their position + */ +static int +shuffle(gf *pkt[], int index[], int k) +{ + int i; + + for ( i = 0 ; i < k ; ) { + if (index[i] >= k || index[i] == i) + i++ ; + else { + /* + * put pkt in the right position (first check for conflicts). + */ + int c = index[i] ; + + if (index[c] == c) { + DEB(PRINT_ERR((mcl_stderr, "\nshuffle, error at %d\n", i))) + return 1 ; + } + SWAP(index[i], index[c], int) ; + SWAP(pkt[i], pkt[c], gf *) ; + } + } + DEB( /* just test that it works... */ + for ( i = 0 ; i < k ; i++ ) { + if (index[i] < k && index[i] != i) { + PRINT_ERR((mcl_stderr, "shuffle: after\n")) + for (i=0; ik ; + gf *p, *matrix = NEW_GF_MATRIX(k, k); + + TICK(ticks[9]); + for (i = 0, p = matrix ; i < k ; i++, p += k ) { +#if 1 /* this is simply an optimization, not very useful indeed */ + if (index[i] < k) { + bzero(p, k*sizeof(gf) ); + p[i] = 1 ; + } else +#endif + if (index[i] < code->n ) + bcopy( &(code->enc_matrix[index[i]*k]), p, k*sizeof(gf) ); + else { + PRINT_ERR((mcl_stderr, "decode: invalid index %d (max %d)\n", + index[i], code->n - 1 )) + free(matrix); + return NULL ; + } + } + TICK(ticks[9]); + if (invert_mat(matrix, k)) { + free(matrix); + matrix = NULL ; + } + TOCK(ticks[9]); + return matrix ; +} + +/* + * fec_decode receives as input a vector of packets, the indexes of + * packets, and produces the correct vector as output. + * + * Input: + * code: pointer to code descriptor + * pkt: pointers to received packets. They are modified + * to store the output packets (in place) + * index: pointer to packet indexes (modified) + * sz: size of each packet + */ +/* + * VR: changed for C++ compilers who don't accept diff in parameters... + * Use a definition that matches prototype in fec.h + */ +#define CPLUSPLUS_COMPATIBLE /* VR: added */ +#ifdef CPLUSPLUS_COMPATIBLE +int +fec_decode(void *code_vp, void **pkt_vp, int index[], int sz) +#else +int +fec_decode(struct fec_parms *code, gf *pkt[], int index[], int sz) +#endif +{ +#ifdef CPLUSPLUS_COMPATIBLE + struct fec_parms *code = (struct fec_parms*)code_vp;/* VR */ + gf **pkt = (gf**)pkt_vp; /* VR */ +#endif /* CPLUSPLUS_COMPATIBLE */ + gf *m_dec ; + gf **new_pkt ; + int row, col , k = code->k ; + + if (GF_BITS > 8) + sz /= 2 ; + + if (shuffle(pkt, index, k)) /* error if true */ + return 1 ; + m_dec = build_decode_matrix(code, pkt, index); + + if (m_dec == NULL) + return 1 ; /* error */ + /* + * do the actual decoding + */ + new_pkt = (gf **)my_malloc (k * sizeof (gf * ), "new pkt pointers" ); + for (row = 0 ; row < k ; row++ ) { + if (index[row] >= k) { + new_pkt[row] = (gf *)my_malloc (sz * sizeof (gf), "new pkt buffer" ); + bzero(new_pkt[row], sz * sizeof(gf) ) ; + for (col = 0 ; col < k ; col++ ) + addmul(new_pkt[row], pkt[col], m_dec[row*k + col], sz) ; + } + } + /* + * move pkts to their final destination + */ + for (row = 0 ; row < k ; row++ ) { + if (index[row] >= k) { + bcopy(new_pkt[row], pkt[row], sz*sizeof(gf)); + free(new_pkt[row]); + } + } + free(new_pkt); + free(m_dec); + + return 0; +} + +/*********** end of FEC code -- beginning of test code ************/ + +#if (TEST || DEBUG) +void +test_gf() +{ + int i ; + /* + * test gf tables. Sufficiently tested... + */ + for (i=0; i<= GF_SIZE; i++) { + if (gf_exp[gf_log[i]] != i) + PRINT_ERR((mcl_stderr, "bad exp/log i %d log %d exp(log) %d\n", + i, gf_log[i], gf_exp[gf_log[i]])) + + if (i != 0 && gf_mul(i, inverse[i]) != 1) + PRINT_ERR((mcl_stderr, "bad mul/inv i %d inv %d i*inv(i) %d\n", + i, inverse[i], gf_mul(i, inverse[i]) )) + if (gf_mul(0,i) != 0) + PRINT_ERR((mcl_stderr, "bad mul table 0,%d\n",i)) + if (gf_mul(i,0) != 0) + PRINT_ERR((mcl_stderr, "bad mul table %d,0\n",i)) + } +} +#endif /* TEST */ + +#endif /* FEC */ + diff --git a/src/common/rse_fec.h b/src/common/rse_fec.h new file mode 100644 index 0000000..97cfddb --- /dev/null +++ b/src/common/rse_fec.h @@ -0,0 +1,58 @@ +/* $Id: rse_fec.h,v 1.2 2003/12/17 16:28:27 roca Exp $ */ +/* + * fec.c -- forward error correction based on Vandermonde matrices + * 980624 + * (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it) + * + * Portions derived from code by Phil Karn (karn@ka9q.ampr.org), + * Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari + * Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995 + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, + * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, + * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY + * OF SUCH DAMAGE. + */ + +/* + * The following parameter defines how many bits are used for + * field elements. The code supports any value from 2 to 16 + * but fastest operation is achieved with 8 bit elements + * This is the only parameter you may want to change. + */ +/* + * VR: warning, this file must not be included by rse_fec.c, this is + * only the external interface used by other files like mcl_fec.cpp + */ +#ifndef GF_BITS +#define GF_BITS 8 /* code over GF(2**GF_BITS) - change to suit */ +#endif + +#define GF_SIZE ((1 << GF_BITS) - 1) /* powers of \alpha */ +extern void fec_free(void *p) ; +extern void * fec_new(int k, int n) ; + +extern void init_fec(void) ; +extern void fec_encode(void *code, void **src, void *dst, int index, int sz) ; +extern int fec_decode(void *code, void **pkt, int index[], int sz) ; + +/* end of file */ diff --git a/src/common/ssm_for_linux.h b/src/common/ssm_for_linux.h new file mode 100755 index 0000000..8cadd43 --- /dev/null +++ b/src/common/ssm_for_linux.h @@ -0,0 +1,62 @@ +/* $Id: ssm_for_linux.h,v 1.1 2005/05/24 10:36:20 roca Exp $ */ +/* + * MAD-ALC, implementation of ALC/LCT protocols + * Copyright (c) 2003-2004 TUT - Tampere University of Technology + * main authors/contacts: jani.peltotalo@tut.fi and sami.peltotalo@tut.fi + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +/* + * All of the below should be in linux/in.h on new enough systems, and + * so there's an attempt to protect them with an #ifdef + */ + +#ifdef LINUX + +#ifndef IP_ADD_SOURCE_MEMBERSHIP + +/* Order within structures is important, the kernel assumes its own + structure layout */ + +struct ip_mreq_source { + struct in_addr imr_multiaddr; /* IP address of group */ + struct in_addr imr_interface; /* IP address of interface */ + struct in_addr imr_sourceaddr; /* IP address of source */ +}; + +#define IP_ADD_SOURCE_MEMBERSHIP 39 +#define IP_DROP_SOURCE_MEMBERSHIP 40 + +#endif + +#ifndef MCAST_JOIN_SOURCE_GROUP + struct group_req { + uint32_t gr_interface; /* interface index */ + struct sockaddr_storage gr_group; /* group address */ + }; + + struct group_source_req { + uint32_t gsr_interface; /* interface index */ + struct sockaddr_storage gsr_group; /* group address */ + struct sockaddr_storage gsr_source; /* source address */ + }; + +#define MCAST_JOIN_SOURCE_GROUP 46 +#define MCAST_LEAVE_SOURCE_GROUP 47 + +#endif + +#endif diff --git a/src/flute_lib/Flute.cpp b/src/flute_lib/Flute.cpp new file mode 100644 index 0000000..2e4aad1 --- /dev/null +++ b/src/flute_lib/Flute.cpp @@ -0,0 +1,674 @@ +/* $Id: Flute.cpp,v 1.7 2005/05/24 09:56:15 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "flute_includes.h" + + +/** + * Flute constructor + */ +Flute::Flute () { + + flutecb = new flute_cb(); + +} + + +/** + * Flute destructor + */ +Flute::~Flute () { + + /* KILL threads */ + + if (flutecb->id != 0) mcl_close(flutecb->id); + delete flutecb; + +} + + +/** + * Abort the current Flute session + */ +void Flute::abort () { + + if (flutecb->id != 0) mcl_abort(flutecb->id); + +} + + +/** + * Print an mcl about (showing compile options, version, etc.) + */ +void Flute::about () { + + flutecb->lock(); + + if (mcl_ctl(flutecb->id, MCL_OPT_MOREABOUT, NULL, 0)) + EXIT(("Flute: Usage: mcl_ctl failed for MOREABOUT\n")) + + flutecb->unlock(); +} + + +/** + * Sets the mcl verbosity level + * @param verbosity verbosity level + */ +void Flute::setVerbosity (INT32 verbosity) { + + flutecb->lock(); + + flutecb->verbose = verbosity; + flutecb->stats = 2; + + flutecb->unlock(); + +} + + +/** + * Get the mcl verbosity level used + * @return verbosity level + */ +INT32 Flute::getVerbosity () { + + INT32 result; + flutecb->lock(); + result = flutecb->verbose; + flutecb->unlock(); + return result; + + +} + + +/** + * Sets the mcl stat level + * @param stats statistic level + */ +void Flute::setStatsLevel (INT32 stats) { + + flutecb->lock(); + + flutecb->stats = stats; + + flutecb->unlock(); + +} + + +/** + * Get the mcl stat level used + * @return statistic level + */ +INT32 Flute::getStatsLevel () { + + INT32 result; + flutecb->lock(); + result = flutecb->stats; + flutecb->unlock(); + return result; + +} + + +/** + * Sets the congestion control scheme: + * INVALID_CC: initial value, nothing choosen + * NO_CC: choose not to have any CC + * RLC_CC: choose to have RLC CC + * FLID_SL_CC: choose to have FLID SL (static layer) CC + * @param cc_scheme the congestion control scheme + */ +void Flute::setCCScheme (INT32 cc_scheme) { + + flutecb->lock(); + + flutecb->congestion_control = cc_scheme; + if (flutecb->congestion_control == NO_CC && flutecb->nb_layers == 0) flutecb->nb_layers = 1; + + flutecb->unlock(); + +} + + +/** + * Sets the transmission profile: + * MCL_TX_PROFILE_LOW_RATE_INTERNET: modem connection + * MCL_TX_PROFILE_MID_RATE_INTERNET: eg with VPNs, xDSL + * MCL_TX_PROFILE_HIGH_SPEED_INTERNET: several Mbps connection + * MCL_TX_PROFILE_HIGH_SPEED_LAN + * @param tx_profile the transmission profile + */ +void Flute::setTxProfile (INT32 tx_profile) { + + flutecb->lock(); + + flutecb->txprof_mode = tx_profile; + if (flutecb->txprof_mode == MCL_TX_PROFILE_HIGH_SPEED_LAN) + flutecb->congestion_control = NO_CC; /* true in a LAN! */ + flutecb->txprof_set = true; + + flutecb->unlock(); + +} + + +/** + * Sets the datagram size in bytes. + * @param dt_size datagram size in bytes + */ +void Flute::setDatagramSize (INT32 dt_size) { + + flutecb->lock(); + + flutecb->txprof_dt_size = dt_size; + + flutecb->unlock(); + +} + + +/** + * Sets the tx rate (in bits/sec). + * @param tx_rate transmission rate in bits/s + */ +void Flute::setTxRate (INT32 tx_rate) { + + flutecb->lock(); + + if (tx_rate > 0) { + flutecb->txprof_rate = (double)tx_rate / + ((double)flutecb->txprof_dt_size * 8.0); + /* no less than 1 pkt/s */ + flutecb->txprof_rate = max(1.0, flutecb->txprof_rate); + } + + flutecb->unlock(); + +} + + +/** + * Sets the nb of layers used. + * @param nb_layers the number of layers + */ +void Flute::setNbLayers (INT32 nb_layers) { + + flutecb->lock(); + + flutecb->nb_layers = nb_layers; + + flutecb->unlock(); + +} + + +/** + * Sets the IP version used. + * @param ip_version the ip version + */ +#ifdef WIN32 +void Flute::setIpVersion (INT32 ip_version) { + + flutecb->lock(); + + flutecb->ip_version = ip_version; + if (flutecb->ip_version != 4 && flutecb->ip_version !=6) + { + EXIT(("Flute: ERROR, unknown IP version %i. Specify IP version 4 or 6\n",ip_version)) + } + + flutecb->unlock(); +} +#endif + + +/** + * Sets the SSM (source specific multicast) mode on/off. + * @param set on or off? + */ +void Flute::setSSM (bool set) { + + flutecb->lock(); + + flutecb->ssm = set; + + flutecb->unlock(); +} + + +/** + * Sets the session address on which to send/recv. + * @param session_addr session address + */ +void Flute::setSessionAddr (struct sockaddr *session_addr) { + + flutecb->lock(); + + flutecb->session_addr = session_addr; + + flutecb->unlock(); +} + + +/** + * Sets the session address on which to send/recv. + * @param session_addr_str session address string + */ +void Flute::setSessionAddr (char *session_addr_str) { + + flutecb->lock(); + + strncpy(flutecb->session_addr_str, session_addr_str, sizeof(flutecb->session_addr_str)); + flutecb->session_address_set = true; + + flutecb->unlock(); + +} + + +/** + * Sets the port of the Flute session + * @param port port number of the session + */ +void Flute::setPort (INT32 port) { + + flutecb->lock(); + + flutecb->port = port; + + flutecb->unlock(); + +} + + +#ifndef WIN32 +/** + * Sets the interface to be used for rx and tx. + * @param if_addr_str interface address string + */ +void Flute::setInterface (char *if_addr_str) { + + flutecb->lock(); + + if (flutecb->tools->extract_addr(if_addr_str, &flutecb->mcast_if_addr, 0) < 0) { + EXIT(("Flute: setInterface: ERROR, address extraction failed\n")) + } + + flutecb->unlock(); + +} + + +/** + * Sets the interface to be used for rx and tx. + * @param if_name interface address + */ +void Flute::setInterface (struct sockaddr *if_addr) { + + flutecb->lock(); + + flutecb->mcast_if_addr = if_addr; + + flutecb->unlock(); + +} + + +/** + * Sets the interface to be used for rx and tx. + * @param if_name interface name + */ +void Flute::setInterfaceName (char* if_name) { + + flutecb->lock(); + + flutecb->mcast_if_name = (char *) calloc(1, strlen(if_name) + 1); + if (flutecb->mcast_if_name == NULL) { + EXIT(("Flute: ERROR, calloc failed during Flute::setInterfaceName\n")) + } + strncpy(flutecb->mcast_if_name, if_name, strlen(if_name) + 1); + + flutecb->unlock(); + +} +#endif /* !WIN32 */ + + +/** + * Sets the TSI of the Flute session + * @param tsi tsi of the session + */ +void Flute::setTSI (INT32 tsi) { + + flutecb->lock(); + + flutecb->demux_label = tsi; + + flutecb->unlock(); + +} + + +/** + * Set the temp dir (where temporary files are stored). + * @param tmp_dir name of the temp dir + */ +void Flute::setTmpDir (char * tmp_dir) { + + flutecb->lock(); + + strncpy(flutecb->tmp_dir, tmp_dir, sizeof(flutecb->tmp_dir)); + flutecb->tmp_dir[MAX_PATH + MAX_FILENAME -1] = 0; + /* add final / and \0 if not already present */ + if (tmp_dir[strlen(flutecb->tmp_dir)-1] != '/' && + strlen(tmp_dir) <= MAX_PATH + MAX_FILENAME -2) + strcat(flutecb->tmp_dir, "/"); + flutecb->tmp_dir_set = true; + + flutecb->unlock(); + +} + + +/** + * Creartes an sdp file using the parameters of the current Flute session. + * @param filename of the sdp file + */ +void Flute::createSdp (char* fileparam) { + + flutecb->lock(); + + flutecb->sdp = new FluteSDP(this->flutecb); + flutecb->sdp->generateSDP(fileparam); + delete flutecb->sdp; + flutecb->sdp = NULL; + + flutecb->unlock(); + +} + + +/** + * Parses an sdp file and sets all parameters accordingly. + * @param filename of the sdp file + */ +void Flute::parseSdp (char* fileparam) { + + flutecb->lock(); + + flutecb->sdp = new FluteSDP(this->flutecb); + flutecb->sdp->parseSDP(fileparam); + delete flutecb->sdp; + flutecb->sdp = NULL; + + flutecb->unlock(); +} + + +/** + * Get the port of the Flute session. + * @return port of the flute session + */ +INT32 Flute::getPort () { + + INT32 val; + + flutecb->lock(); + val = flutecb->port; + flutecb->unlock(); + + return val; + +} + + +/** + * Are we are flute sender? + * @return true or false + */ +bool Flute::isSender() { + + + flutecb->lock(); + + if (flutecb->mode == SEND) { + + flutecb->unlock(); + return true; + } + + flutecb->unlock(); + return false; + +} + + +/** + * Are we are flute receiver? + * @return true or false + */ +bool Flute::isReceiver() { + + flutecb->lock(); + + if (flutecb->mode == RECV) { + flutecb->unlock(); + return true; + } + flutecb->unlock(); + return false; +} + + +/** + * Returns file information of the given toi + * @param toi toi of the file + * @return a FluteFileInfo class containing info about the file + * NULL if no file with given toi exists + */ +class FluteFileInfo *Flute::getFileInfo (TOI_t toi) +{ + + class FluteFileInfo* returnedFFileInfo; + flutecb->lock(); + returnedFFileInfo = flutecb->fdt->getFileInfo(toi); + flutecb->unlock(); + + return returnedFFileInfo; + +} + + +/** + * Returns a list of file information. It is a list of files + * contained in the FDT. + * @return a list of FluteFileInfo classes + * containing info about the files + * NULL if FDT is empty. + */ +class FluteFileInfo *Flute::getFileInfoList () +{ + class FluteFileInfo* returnedFFileInfo; + flutecb->lock(); + returnedFFileInfo = flutecb->fdt->getFileInfoList(); + flutecb->unlock(); + + return returnedFFileInfo; + +} + + +/** + * Initialize the ALC library now. + * All selected options are passed to MCL. + */ +void Flute::init () +{ + int err = 0; + + ASSERT(flutecb->mode == SEND || flutecb->mode == RECV); + + /* Process address string */ + if (flutecb->session_address_set == true && + flutecb->tools->extract_addr(flutecb->session_addr_str, &flutecb->session_addr, flutecb->port) < 0) { + EXIT(("Flute: ERROR, extract_addr failed for session addr argument -a%s\n", flutecb->session_addr_str)) + } + + /* Some sanity checks */ + if (flutecb->congestion_control == NO_CC && flutecb->nb_layers > 1) + EXIT(("Flute: ERROR, cannot set nb of layers > 1 with no congestion control\n")) +#ifndef WIN32 + if (flutecb->session_addr != NULL && flutecb->session_addr->sa_family == AF_INET6 && flutecb->mcast_if_name == NULL) + { + EXIT(("Flute: ERROR, you must specify an interface name with IPv6\n")) + } +#endif + if (flutecb->ssm && (flutecb->src_addr == NULL) && (flutecb->mode == RECV)) { + EXIT(("Flute: ERROR, you must specify a source address in SSM/Receiver mode\n")) + } + + /* specify few important parameters... */ + err += mcl_ctl(flutecb->id, MCL_OPT_VERBOSITY, (void*)&flutecb->verbose, sizeof(flutecb->verbose)); + EXIT_ON_ERROR(err, ("Flute: ERROR, mcl_ctl failed for VERBOSITY\n")) + err += mcl_ctl(flutecb->id, MCL_OPT_STATS, + (void*)&flutecb->stats, sizeof(int)); + EXIT_ON_ERROR(err, ("Flute: ERROR, mcl_ctl failed for STATS\n")) + err += mcl_ctl(flutecb->id, MCL_OPT_SET_FLUTE_MODE, NULL, 0); + EXIT_ON_ERROR(err, ("Flute: ERROR, mcl_ctl failed for SET_FLUTE_MODE\n")) + if (flutecb->congestion_control > 0) { /* must be before TX_PROFILE */ + err += mcl_ctl(flutecb->id, MCL_OPT_SET_CC_SCHEME, + (void*)&flutecb->congestion_control, + sizeof(flutecb->congestion_control)); + EXIT_ON_ERROR(err, ( + "Flute: ERROR, mcl_ctl failed for MCL_OPT_SET_CC_SCHEME %d\n", + flutecb->congestion_control)) + } + if (flutecb->txprof_set) { + err += mcl_ctl(flutecb->id, MCL_OPT_TX_PROFILE, (void*)&flutecb->txprof_mode, + sizeof(flutecb->txprof_mode)); + EXIT_ON_ERROR(err, ( + "Flute: ERROR, mcl_ctl failed for TX_PROFILE\n")) + } + if (flutecb->txprof_dt_size > 0) { /* must be after TX_PROFILE */ + err += mcl_ctl(flutecb->id, MCL_OPT_DATAGRAM_SIZE, + (void*)&flutecb->txprof_dt_size, + sizeof(flutecb->txprof_dt_size)); + EXIT_ON_ERROR(err, ( + "Flute: ERROR, mcl_ctl failed for DATAGRAM_SIZE %d\n", + flutecb->txprof_dt_size)) + } + if (flutecb->txprof_rate > 0.0) { /* must be after TX_PROFILE */ + err += mcl_ctl(flutecb->id, MCL_OPT_TX_RATE, + (void*)&flutecb->txprof_rate, + sizeof(flutecb->txprof_rate)); + EXIT_ON_ERROR(err, ( + "Flute: ERROR, mcl_ctl failed for TX_RATE %f\n", + flutecb->txprof_rate)) + } + if (flutecb->nb_layers > 0) { + err += mcl_ctl(flutecb->id, MCL_OPT_LAYER_NB, + (void*)&flutecb->nb_layers, + sizeof(int)); + EXIT_ON_ERROR(err, ("Flute: ERROR, mcl_ctl failed for LAYER_NB\n")) + } + if (flutecb->session_addr != NULL) { + int addr_len; + addr_len = (flutecb->session_addr->sa_family == AF_INET6) ? + sizeof(struct sockaddr_in6) : + sizeof(struct sockaddr_in); + err += mcl_ctl(flutecb->id, MCL_OPT_BIND, + (void*)flutecb->session_addr, addr_len); + EXIT_ON_ERROR(err, ("Flute: ERROR, mcl_ctl failed for BIND\n")) + } + if (flutecb->mcast_if_addr != NULL) { /* in host format! */ + err += mcl_ctl(flutecb->id, MCL_OPT_SET_NETIF_ADDR, + (void*)&flutecb->mcast_if_addr, + sizeof(*flutecb->mcast_if_addr)); + EXIT_ON_ERROR(err, ("Flute: ERROR, mcl_ctl failed for SET_NETIF_ADDR\n")) + } else if (flutecb->mcast_if_name != NULL) { + err += mcl_ctl(flutecb->id, MCL_OPT_SET_NETIF_NAME, + (void*)flutecb->mcast_if_name, + strlen(flutecb->mcast_if_name)); + EXIT_ON_ERROR(err, ("Flute: ERROR, mcl_ctl failed for SET_NETIF_NAME\n")) + } + if (flutecb->ssm == true) { + int val = (int)flutecb->ssm; + err += mcl_ctl(flutecb->id, MCL_OPT_SET_SSM, + (void*)&val, sizeof(val)); + EXIT_ON_ERROR(err, ( + "Flute: ERROR, mcl_ctl failed for DEMUX_LABEL\n")) + } + if (flutecb->demux_label > 0) { + err += mcl_ctl(flutecb->id, MCL_OPT_DEMUX_LABEL, + (void*)&flutecb->demux_label, + sizeof(flutecb->demux_label)); + EXIT_ON_ERROR(err, ( + "Flute: ERROR, mcl_ctl failed for DEMUX_LABEL\n")) + } + if (flutecb->ttl >= 0) { + err += mcl_ctl(flutecb->id, MCL_OPT_TTL, + (void*)&flutecb->ttl, + sizeof(flutecb->ttl)); + EXIT_ON_ERROR(err, ( + "Flute: ERROR, mcl_ctl failed for TTL\n")) + } + if (flutecb->tmp_dir_set) { + err += mcl_ctl(flutecb->id, MCL_OPT_TMP_DIR, + (void*)&flutecb->tmp_dir, + strlen(flutecb->tmp_dir)); + EXIT_ON_ERROR(err, ( + "Flute: ERROR, mcl_ctl failed for TMP_DIR \"%s\"\n", + flutecb->tmp_dir)) + } + + if (flutecb->mode == SEND) { + /* + * always use LCT1 now, in all cases... + */ + int mcl_option = MCL_SCHED_LCT1; + if (mcl_ctl(flutecb->id, MCL_OPT_SCHED, + (void*)&mcl_option, + sizeof(mcl_option))) { + EXIT(("Flute: mcl_ctl MCL_OPT_SCHED failed for LCT1\n")) + } + + } + else if (flutecb->mode == RECV) { + if (flutecb->src_addr != NULL) { + int addr_len; + addr_len = (flutecb->src_addr->sa_family == AF_INET6) ? + sizeof(struct sockaddr_in6) : + sizeof(struct sockaddr_in); + if (mcl_ctl(flutecb->id, MCL_OPT_SRC_ADDR, + (void*)flutecb->src_addr, addr_len)) { + EXIT(("mcl_ctl: MCL_OPT_SRC_ADDR failed\n")) + } + } + + } + flutecb->initialized = true; +} + diff --git a/src/flute_lib/Flute.h b/src/flute_lib/Flute.h new file mode 100644 index 0000000..02ba5f0 --- /dev/null +++ b/src/flute_lib/Flute.h @@ -0,0 +1,122 @@ +/* $Id: Flute.h,v 1.3 2005/05/23 11:11:17 roca Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_H +#define FLUTE_H + +/** + * This Class is the API for flute + */ +class Flute { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + Flute (); + + /** + * Default destructor. + */ + ~Flute (); + + void abort (); + + /********* Low level debug trace functions *******/ + void about (); + + void setVerbosity (INT32 verbosity); + + INT32 getVerbosity (); + + void setStatsLevel (INT32 stats); + + INT32 getStatsLevel (); + + + /******* Common Receiver and Sender options ******/ + void setCCScheme (INT32 cc_scheme); + +#ifdef WIN32 + void setIpVersion (INT32 ip_version); +#endif + + void setSSM (bool set); + + void setSessionAddr (struct sockaddr *session_addr); + + void setSessionAddr (char *session_addr_str); + + void setPort (INT32 port); + + INT32 getPort (); + +#ifndef WIN32 + void setInterface (char *if_addr_str); + + void setInterface (struct sockaddr *if_addr); + + void setInterfaceName (char* if_name); +#endif + + void setTSI (INT32 tsi); + + void setTmpDir (char * tmp_dir); + + /****** SDP functions *****/ + + void createSdp (char* fileparam); + + void parseSdp (char* fileparam); + + + /******* Transmission Profiles *******/ + void setTxProfile (INT32 tx_profile); + + void setDatagramSize (INT32 dt_size); + + void setTxRate (INT32 tx_rate); + + void setNbLayers (INT32 nb_layers); + + /**** Used as Sender or Receiver */ + + bool isSender(); + + bool isReceiver(); + + /**** File Informations */ + + class FluteFileInfo* getFileInfoList (); + + class FluteFileInfo* getFileInfo (TOI_t toi); + + +protected: + void init(); + + class flute_cb* flutecb; /* the flute control block */ + +}; + +#endif diff --git a/src/flute_lib/FluteAPI.h b/src/flute_lib/FluteAPI.h new file mode 100644 index 0000000..b781f13 --- /dev/null +++ b/src/flute_lib/FluteAPI.h @@ -0,0 +1,145 @@ +/* $Id: FluteAPI.h,v 1.2 2005/05/12 16:03:34 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef WIN32 +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif /* OS_DEP */ + +#ifndef ALC +#define ALC +#endif +#include "../common/mcl_lib_api.h" + +#if defined(LINUX) /* On Linux systems, signal handlers must be of __sighandler_t type */ +#define sighandler_t __sighandler_t + +#elif defined(SOLARIS) || defined(IRIX) || defined(WIN32) + +#define sighandler_t void (*)(int) + +#elif defined(FREEBSD) +#define sighandler_t sig_t + +#endif + + +/* lock definitions */ + +#if defined(WIN32) +#define flute_mutex_t CRITICAL_SECTION +#define flute_thread_t HANDLE + +#elif defined(NO_PTHREAD_LOCK) + +#define flute_mutex_t unsigned int +#define flute_thread_t pthread_t + +#else + +#define flute_mutex_t pthread_mutex_t +#define flute_thread_t pthread_t +#endif /* OS */ + + +/** Constants **/ + +#define CONTINUOUS -1 + +#define PROMPT 1 +#define NEVER 2 +#define ALWAYS 3 + + +/****** Profile Constants ******/ + +/* + * Big files are all fragmented into fragments of size at most + * XXX_MAX_FRAGMENT_SIZE bytes. + * Try to make sure that the ALC object total size + * (i.e. XXX_MAX_FRAGMENT_SIZE + MAX_TRAILER_SIZE) is small enough to be + * encoded in a single ALC source block. + * XXX: this is specified statically, should be done by querying MCL + * + * Edit it as appropriate... + */ +/* + * choose the appropriate size according to the FEC codec used by MCL + */ +#define RSE_MAX_FRAGMENT_SIZE (64*1024) // 65535 bytes +#define LDGM_MAX_FRAGMENT_SIZE (20*1024*1024) // 20 MB +#define NULL_FEC_MAX_FRAGMENT_SIZE (1*1024*1024) // 1 MB + +/* + * Files larger than this size should be handled by LDGM-*, others by RSE. + * NB: RSE is more efficient than LDGM-* even if a few blocks are needed. + * Above a certain threshold, this is no longer true. + */ +#define RSE_LDGM_FILE_SIZE_THRESHOLD (20 * RSE_MAX_FRAGMENT_SIZE) + +/* + * choose the appropriate maximum size + */ +#define FLUTE_MAX_FDT_SIZE (64*1024) // 64 KB +#define FLUTE_MAX_FILE_SIZE (100*1024*1024) // 100 MB + + +/* Maximum number of files supported by flute */ +#define MAXNUMBER_OF_FILES 500 + +/* path and file name length */ +#ifndef MAX_PATH +#define MAX_PATH 1024 +#endif + +#define MAX_FILENAME 512 + +/* includes */ + +#include "Flute.h" +#include "FluteReceiver.h" +#include "FluteSender.h" +#include "FluteFileInfo.h" +#include "FluteFileDeliveryCarousel.h" diff --git a/src/flute_lib/FluteFDT.cpp b/src/flute_lib/FluteFDT.cpp new file mode 100644 index 0000000..d28c312 --- /dev/null +++ b/src/flute_lib/FluteFDT.cpp @@ -0,0 +1,917 @@ +/* $Id: FluteFDT.cpp,v 1.2 2005/05/12 16:03:34 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "flute_includes.h" + +/** + * Creates the FDT + */ +FluteFDT::FluteFDT(class flute_cb * flutecb) +{ + XMLCh tempStr[100]; + + this->flutecb=flutecb; + + try + { + XMLPlatformUtils::Initialize(); + } + catch (const XMLException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); + EXIT(("Error during initialization:\n\t %s\n", message)) + } + + /* First I get a DOMImplementation reference */ + XMLString::transcode("XML 1.0 XML 2.0 Range 2.0 Traversal 2.0", tempStr, 99); + impl = DOMImplementationRegistry::getDOMImplementation(tempStr); + + /* Initialize the dom_builder */ + dom_builder = ((DOMImplementationLS*)impl)->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0); + + /* I create a new document with FDT as root element */ + XMLString::transcode("FDT", tempStr, 99); + doc = impl->createDocument(0, tempStr, 0); + + fdt_lifetime = FDT_LIFETIME; + + /* Now handle the expires attribute */ + if (fdt_lifetime == 0) + { + /* set the maximum expiration time */ + setExpires("4294967294"); + } + else + { + time_t systime; + char * str_time = (char *) calloc(1,10); //10 is maximum length of UL string + UINT64 currenttime; + + time(&systime); + currenttime = (UINT64) systime + (UINT64) 2208988800; + +#ifdef WIN32 + sprintf(str_time,"%I64u",currenttime + fdt_lifetime); +#else + sprintf(str_time,"%llu",currenttime + fdt_lifetime); +#endif + setExpires(str_time); + free(str_time); + } + +} + +/** + * Closes and frees the FDT + */ +FluteFDT::~FluteFDT() +{ + + /* I free the document structure */ + doc->release(); + + XMLPlatformUtils::Terminate(); +} + + +/** + * Checks if object with a given toi is described in FDT. + * @param toi TOI of the object + * @return true if described in the FDT, else false. + */ +bool FluteFDT::hasTOIinFDT(UINT64 toi){ + + XMLCh tempStr[100]; + unsigned int i, nchilds; + bool hasTOI = false; + + try + { + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + XMLString::transcode("File", tempStr, 99); + DOMNodeList* node_list = root->getElementsByTagName(tempStr); + + nchilds = node_list->getLength(); + XMLString::transcode("TOI", tempStr, 99); + for (i = 0; i < nchilds; i++) { + DOMNode* node = node_list->item(i); + DOMAttr* pAttr = ((DOMElement *) node)->getAttributeNode(tempStr); + const XMLCh* toi_value = pAttr->getValue(); + if(toi==(UINT64) XMLString::parseInt(toi_value)) + { + hasTOI=true; + break; + } + } + } + catch (const DOMException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); + EXIT(("Error during hasTOIinFDT(UINT64 toi):\n\t %s\n", message)) + } + + return hasTOI; + +} + + +/** + * Sets value of an elements attribute. Attribute is created if needed. + * @param el pointer to the element + * @param name name of the attribute + * @param value value of the attribute + * @return the updated element el. + */ +DOMElement* FluteFDT::setAttribute(DOMElement* el, char * name, char* ivalue) +{ + XMLCh tempStr[100]; + + try + { + /*Get the attribute*/ + XMLString::transcode(name, tempStr, 99); + DOMAttr* pAttr; + if ((pAttr = el->getAttributeNode(tempStr))== NULL) + { + pAttr = doc->createAttribute(tempStr); + el->setAttributeNode(pAttr); + } + + /* fix the URI if it is the Content-Location attribute */ + if (strncmp(name,"Content-Location",16)==0) + { + XMLCh tempStr2[100]; + XMLCh tempStr3[100]; + XMLString::transcode(ivalue, tempStr3, 99); + XMLString::fixURI(tempStr3, tempStr2); + pAttr->setValue((const XMLCh *)tempStr2); + } + else if (strncmp(name,"Expires",7)==0) + { + /* we need this since otherwise transcode + * transforms the string into a false integer string + */ + pAttr->setValue((const XMLCh *)ivalue); + } + else + { + XMLString::transcode(ivalue, tempStr, 99); + pAttr->setValue((const XMLCh *)tempStr); + } + + + } + catch (const DOMException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); + EXIT(("Error during setAttribute(DOMElement* el, char * name, char* ivalue):\n\t %s\n", message)) + } + + return el; +} + + +/** + * Check if the timestamp passed as character string expired, + * i.e. timestamp < time_now. + * @param ivalue character string of the timestamp value + */ +void FluteFDT::checkExpires(char * ivalue) +{ + time_t systime; + time(&systime); + +#ifdef WIN32 + if ((UINT64) systime + (UINT64) 2208988800 >= _atoi64(ivalue)) +#else + if ((UINT64) systime + (UINT64) 2208988800 >= strtoull(ivalue,NULL,10)) +#endif + { + char * str_time = (char *) malloc(10); //10 is maximum length of UL string + sprintf(str_time,"%llu", (UINT64) systime); + free(str_time); + EXIT(("FDT Instance expired: Expires at %s and it is %s\n", ivalue , str_time)) + } + +} + + +/** + * Sets the Expires attribute of the FDT. + * @param ivalue character string of the timestamp value + */ +void FluteFDT::setExpires(char * ivalue) +{ + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + setAttribute(root, "Expires", ivalue); +} + +/** + * Returns the Expires attribute of the FDT. + * @return character string of the Expires timestamp value + */ +char * FluteFDT::getExpires() +{ + XMLCh tempStr[100]; + char * result; + + try + { + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + /*Get the expires attribute*/ + XMLString::transcode("Expires", tempStr, 99); + DOMAttr* pAttr = root->getAttributeNode(tempStr); + + const XMLCh* value = pAttr->getValue(); + + result = (char *) value; + } + catch (const XMLException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); + EXIT(("Error during getExpires():\n\t %s\n", message)) + } + + return result; +} + +/** + * Returns the Complete attribute of the FDT. + * @return true if complete == true; else false. + */ +bool FluteFDT::isComplete() +{ + XMLCh tempStr[100]; + + try + { + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + /*Get the expires attribute*/ + XMLString::transcode("Complete", tempStr, 99); + DOMAttr* pAttr = root->getAttributeNode(tempStr); + + if (pAttr == NULL) return false; + + const XMLCh* value = pAttr->getValue(); + + if (value == false) return false; + + } + catch (const XMLException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); + EXIT(("Error during isComplete():\n\t %s\n", message)) + } + + return true; +} + + + + + +/** + * Update the FDT. Adds elements of the FDTinstance to the FDT + * @param xmlfdtinstance pointer to the buffer containing the xml + * string of the fdt instance + * @param length len of the xml string of the fdt instance + */ +void FluteFDT::updateFDT(char* xmlfdtinstance, unsigned int length) +{ + XMLCh tempStr[100]; + + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* fdtinstance; + + try { + +#if 0 /* validate the fdt_instance, doesn't seem to work. TODO: fixit*/ + /* First validate the xml file using the FLUTE Schema */ + SAXParser* parser = new SAXParser; + parser->setValidationScheme(SAXParser::Val_Always); + parser->setDoNamespaces(true); + parser->setDoSchema(true); + parser->setDoValidation(true); + parser->setValidationSchemaFullChecking(true); + parser->setValidationConstraintFatal(true); + parser->setExternalNoNamespaceSchemaLocation("FLUTE_SCHEMA.xsd"); + parser->setExternalSchemaLocation("FLUTE_SCHEMA.xsd"); + parser->parse(*(new MemBufInputSource((const XMLByte *) xmlfdtinstance,length, tempStr))); + delete parser; +#endif + + /*Then build the DOM tree*/ + const DOMInputSource* domIS = new Wrapper4InputSource(new MemBufInputSource((const XMLByte *) xmlfdtinstance,length, tempStr)); + fdtinstance = dom_builder->parse(*domIS); + delete domIS; + + } + catch (const XMLException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); + EXIT(("Exception message is: %s\n", message)) + } + + /* I get reference to the root element of the document */ + DOMElement* fdt_instance_root; + if ((fdt_instance_root = fdtinstance->getDocumentElement()) == NULL) + { + EXIT(("Root element is null\n")) + } + + /* Check Expires node */ + XMLString::transcode("Expires", tempStr, 99); + DOMAttr* pAttr = fdt_instance_root->getAttributeNode(tempStr); + const XMLCh* value = pAttr->getValue(); + char * temp_char = XMLString::transcode(value); + checkExpires(temp_char); + free(temp_char); + + /* Go through the attributes of the instance root element and check if it is already included in the FDT */ + DOMNamedNodeMap * node_map = fdt_instance_root->getAttributes(); + long i,nattr; + nattr = node_map->getLength(); + for (i = 0; i < nattr; i++) { + DOMNode* node = node_map->item(i); + if (node->getNodeType() == DOMNode::ATTRIBUTE_NODE) + { + const XMLCh* name; + char * temp_char2; + value = ((DOMAttr*) node)->getValue(); + name = ((DOMAttr*) node)->getName(); + temp_char = XMLString::transcode(value); + temp_char2 = XMLString::transcode(name); + setAttribute(root, temp_char2, temp_char); + free(temp_char2); + free(temp_char); + } + } + + /* Go through the child-nodes elements of the instance and check if it is already included in the FDT */ + DOMNodeList* node_list = fdt_instance_root->getChildNodes(); + + long nchilds; + nchilds = node_list->getLength(); + XMLString::transcode("TOI", tempStr, 99); + for (i = 0; i < nchilds; i++) { + DOMNode* node = node_list->item(i); + if (node->getNodeType() == DOMNode::ELEMENT_NODE) + { + pAttr = ((DOMElement *) node)->getAttributeNode(tempStr); + value = pAttr->getValue(); + if(! hasTOIinFDT((UINT64) XMLString::parseInt(value)) ) + { + DOMNode* new_node = doc->importNode(node,true); + root->appendChild(new_node); + } + } + } + fdtinstance->release(); +} + + +/** + * Adds the file with the given toi of the FDT + * to the FileList and signal the selection to mclv3. + * @param filelist list of files, where new has to be added to + * @param toi toi of the file that has to be added + */ + +void FluteFDT::selectTOI(class FluteFileList *filelist, TOI_t toi) +{ + XMLCh tempStr[100]; + DOMNode* node = NULL; + unsigned int i, nchilds; + + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + XMLString::transcode("File", tempStr, 99); + DOMNodeList* node_list = root->getElementsByTagName(tempStr); + + nchilds = node_list->getLength(); + XMLString::transcode("TOI", tempStr, 99); + for (i = 0; i < nchilds; i++) { + DOMNode* temp_node = node_list->item(i); + DOMAttr* pAttr = ((DOMElement *) temp_node)->getAttributeNode(tempStr); + const XMLCh* toi_value = pAttr->getValue(); + if(toi==(unsigned int) XMLString::parseInt(toi_value)) + { + node = temp_node; + break; + } + } + + if (node == NULL) { + return; + } + else + { + class FluteFile *NewFile = new FluteFile(this->flutecb); + + /* Content-Location */ + XMLString::transcode("Content-Location", tempStr, 99); + DOMAttr* pAttr = ((DOMElement *) node)->getAttributeNode(tempStr); + const XMLCh* value = pAttr->getValue(); + char * temp_char = XMLString::transcode(value); + + /* Remove string file:// */ + if (XMLString::startsWith(temp_char,"file://")) + { + int len = strlen(temp_char); + strncpy(temp_char, temp_char + 7, len - 7); + temp_char[len - 7] = '\0'; + } + + /* Detect possible ':' (like c:/) and replace them with '/' */ + char *p; + if ((p = strchr(temp_char, ':')) != NULL) { + *p = '/'; + } + + strncpy(NewFile->fullname,"./", 2); /* just to be sure it is copied in current directory */ + strncpy(NewFile->fullname+2, temp_char, MAX_PATH+MAX_FILENAME ); + NewFile->writeIt = FluteFile::CheckWriteContext(flutecb, NewFile->fullname, flutecb->overwrite); + NewFile->received=0; + NewFile->selected=1; + NewFile->toi = toi; + NewFile->integrity =0; + NewFile->nextFile = NULL; + + free(temp_char); + + /* Content-Length */ + NewFile->contentLength=0; + XMLString::transcode("Content-Length", tempStr, 99); + if ((pAttr = ((DOMElement *) node)->getAttributeNode(tempStr))!=NULL) + { + value = pAttr->getValue(); + NewFile->contentLength = (unsigned long) XMLString::parseInt(value); + } + + /*We assume transferLength = contentLength */ + NewFile->transferLength = NewFile->contentLength; + +#if OPENSSL + /* Content-MD5 */ + XMLString::transcode("Content-MD5", tempStr, 99); + memset(NewFile->md5sum, 0, MD5BASE64_LENGTH); + if ((pAttr = ((DOMElement *) node)->getAttributeNode(tempStr))!=NULL) + { + value = pAttr->getValue(); + char * temp_char2 = XMLString::transcode(value); + strncpy((char *)NewFile->md5sum ,temp_char,MD5BASE64_LENGTH); + free(temp_char2): + } +#else + memset(NewFile->md5sum, 0, MD5BASE64_LENGTH); + //ZeroMemory(NewFile.md5sum, MD5BASE64_LENGTH); +#endif + filelist->FFileInsert(NewFile); + + /* Now signal it to mclv3 */ + { + int mcl_option = NewFile->toi; + if (mcl_ctl(flutecb->id, MCL_OPT_FLUTE_DELIVER_THIS_ADU_TO_APPLI, (void*)&mcl_option, sizeof(mcl_option))) + EXIT(("mcl_ctl: MCL_OPT_FLUTE_DELIVER_THIS_ADU_TO_APPLI failed\n")) + + /* Get FTI info if there is ... */ + + FTI_infos_t FTI_infos; + memset(&FTI_infos, 0, sizeof(FTI_infos)); + + FTI_infos.toi = NewFile->toi; + FTI_infos.adu_len = NewFile->contentLength; + + /* First check if there is FTI info at File element node then at FDT-Instance root */ + if ((getFTIinfos(node, &FTI_infos) == true) || (getFTIinfos(root, &FTI_infos) == true)) + { + if (mcl_ctl(flutecb->id, MCL_OPT_SET_FTI_INFO, (void*)&FTI_infos, sizeof(FTI_infos))) + EXIT(("mcl_ctl: MCL_OPT_SET_FTI_INFO failed\n")) + } + } + + + + } + +} + +/** + * Adds all elements of the FDT to the FileList + * ONLY in !interactive mode. + * @param filelist file list that needs to be updated + */ +void FluteFDT::selectAllTOIs(class FluteFileList *filelist) +{ + + XMLCh tempStr[100]; + + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + /* Go through the nodelist*/ + DOMNodeList* node_list = root->getChildNodes(); + + long i, nchilds; + nchilds = node_list->getLength(); + XMLString::transcode("TOI", tempStr, 99); + for (i = 0; i < nchilds; i++) { + DOMNode* node = node_list->item(i); + if (node->getNodeType() == DOMNode::ELEMENT_NODE) + { + DOMAttr* pAttr = ((DOMElement *) node)->getAttributeNode(tempStr); + const XMLCh* value = pAttr->getValue(); + if(((filelist->FFileFindTOI(XMLString::parseInt(value)))==NULL)) + { + selectTOI(filelist, XMLString::parseInt(value)); + } + } + } +} + + + +/** + * Gathers FTI information for a given node, and updates + * FTI_infos accordingly. + * @param nodeToCheck node where to search FTI infos + * @param FTI_infos struct that needs to be updated, containing all FTI information. + * @return true if FTI information found, false if not. + */ +bool FluteFDT::getFTIinfos(DOMNode* nodeToCheck, FTI_infos_t * FTI_infos) +{ + XMLCh tempStr[100]; + DOMAttr* pAttr; + const XMLCh* value; + + try + { + + /* FEC-OTI-FEC-Encoding-ID */ + XMLString::transcode("FEC-OTI-FEC-Encoding-ID", tempStr, 99); + if ((pAttr = ((DOMElement *) nodeToCheck)->getAttributeNode(tempStr))!=NULL) + { + value = pAttr->getValue(); + FTI_infos->fec_encoding_id = (UINT32) XMLString::parseInt(value); + } + else return false; + + + /* FEC-OTI-FEC-Instance-ID */ + /* is not always transmitted (only for underspecified schemes) */ + XMLString::transcode("FEC-OTI-FEC-Instance-ID", tempStr, 99); + if ((pAttr = ((DOMElement *) nodeToCheck)->getAttributeNode(tempStr))!=NULL) + { + value = pAttr->getValue(); + FTI_infos->fec_instance_id = (UINT16) XMLString::parseInt(value); + } + else if (FTI_infos->fec_encoding_id > 127) + /* FEC-Instance-ID is required for underspecified schemes */ + return false; + + + /* FEC-OTI-Maximum-Source-Block-Length */ + XMLString::transcode("FEC-OTI-Maximum-Source-Block-Length", tempStr, 99); + if ((pAttr = ((DOMElement *) nodeToCheck)->getAttributeNode(tempStr))!=NULL) + { + value = pAttr->getValue(); + FTI_infos->max_k = (UINT32) XMLString::parseInt(value); + } + else return false; + + + /* FEC-OTI-Encoding-Symbol-Length */ + XMLString::transcode("FEC-OTI-Encoding-Symbol-Length", tempStr, 99); + if ((pAttr = ((DOMElement *) nodeToCheck)->getAttributeNode(tempStr))!=NULL) + { + value = pAttr->getValue(); + FTI_infos->symbol_len = (UINT16) XMLString::parseInt(value); + } + else return false; + + + /* FEC-OTI-Max-Number-of-Encoding-Symbols */ + /* is not always transmitted (depending on the FEC scheme) */ + XMLString::transcode("FEC-OTI-Max-Number-of-Encoding-Symbols", tempStr, 99); + if ((pAttr = ((DOMElement *) nodeToCheck)->getAttributeNode(tempStr))!=NULL) + { + value = pAttr->getValue(); + FTI_infos->max_n = (UINT32) XMLString::parseInt(value); + } + + + /* FEC-OTI-Seed */ + /* is not always transmitted (depending on the FEC scheme) */ + XMLString::transcode("FEC-OTI-Seed", tempStr, 99); + if ((pAttr = ((DOMElement *) nodeToCheck)->getAttributeNode(tempStr))!=NULL) + { + value = pAttr->getValue(); + FTI_infos->fec_key = (UINT32) XMLString::parseInt(value); + } + + } catch (const XMLException& toCatch) { + char* message = XMLString::transcode(toCatch.getMessage()); + EXIT(("Error during getFTIinfos():\n\t %s\n", message)) + } + + return true; + +} + + +/** + * Creates a new File Element, that may be added to the FDT + * @return the new File element + */ + +DOMElement* FluteFDT::createNewFile() +{ + + XMLCh tempStr[100]; + + XMLString::transcode("File", tempStr, 99); + DOMElement* el = doc->createElement(tempStr); + + return el; +} + + +/** + * Appends a File Element to the FDT + * @param el element that has to be appended to the FDT + */ + +void FluteFDT::appendFile(DOMElement *el) +{ + + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + /* append the node */ + root->appendChild (el); + +} + +/** + * Creates a new (empty) FDT instance, taking the FDT as a basis. + * @return the FDT instance + */ +XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* FluteFDT::createNewFDTinstance() +{ + + + XMLCh tempStr1[100]; + XMLCh tempStr2[100]; + + /* I create a new document with FDT as root element */ + XMLString::transcode("FDT-Instance", tempStr1, 99); + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* fdtinstance = impl->createDocument(0, tempStr1, 0); + + /* I get reference to the root element of the document */ + DOMElement* root = fdtinstance->getDocumentElement(); + + /* I add the Expires attribute to the element */ + XMLString::transcode("Expires", tempStr1, 99); + XMLString::transcode(getExpires(), tempStr2, 99); + root->setAttribute (tempStr1, tempStr2); + + return fdtinstance; +} + + +/** + * Adds a file to the FDT instance. + * @param fdtinstance the FDT instance + * @param itoi the toi of the file that has to added + * @return the updated FDT instance + */ +XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* FluteFDT::AddFileToFDTinstance(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* fdtinstance ,unsigned int itoi) +{ + + XMLCh tempStr[100]; + + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + /* Go through the nodelist*/ + DOMNodeList* node_list = root->getChildNodes(); + + long i, nchilds; + nchilds = node_list->getLength(); + XMLString::transcode("TOI", tempStr, 99); + for (i = 0; i < nchilds; i++) { + DOMNode* node = node_list->item(i); + if (node->getNodeType() == DOMNode::ELEMENT_NODE) + { + DOMAttr* pAttr = ((DOMElement *) node)->getAttributeNode(tempStr); + const XMLCh* toi_value = pAttr->getValue(); + if(itoi==(unsigned int) XMLString::parseInt(toi_value)) + { + /* I get reference to the root element of the document */ + DOMElement* root_instance = fdtinstance->getDocumentElement(); + DOMNode* new_node = fdtinstance->importNode(node,true); + root_instance->appendChild(new_node); + + } + + } + } + + return fdtinstance; + +} + +/** + * Creates the FDT instance xml-string. + * @param fdtinstance the FDT instance + * @param buffer outputbuffer containing the xml string, allocated by the callee + * @return length of the xml string + */ +unsigned int FluteFDT::getFinalFDTInstance(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* fdtinstance, char ** buffer) +{ + XMLCh tempStr2[100]; + unsigned int len = 0; + + if (fdtinstance == NULL) + { + return 0; + } + + DOMWriter* theSerializer = ((DOMImplementationLS*)impl)->createDOMWriter(); + + XMLString::transcode("UTF-8", tempStr2, 99); + theSerializer->setEncoding(tempStr2); + + MemBufFormatTarget * target = new MemBufFormatTarget(FLUTE_MAX_FDT_SIZE); + + theSerializer->writeNode(target,*fdtinstance); + + len = target->getLen(); + + *buffer = (char*) malloc(len); + + memcpy(*buffer, (char*) target->getRawBuffer(), len); + + theSerializer->release(); + delete target; + + return len; +} + + +class FluteFileInfo *FluteFDT::getFileInfoList() +{ + + class FluteFileInfo * returnedList = NULL; + class FluteFileInfo * returnedListElement = NULL; + + XMLCh tempStr[100]; + unsigned int i; /* current index while crossing the DOM node list. */ + unsigned int nchilds; + + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + DOMNodeList* node_list = root->getChildNodes(); + if ((nchilds = node_list->getLength())==0) { + return NULL; + } + /* + * Now go through all entries in the DOM node list... + */ + for (i = 0; i < nchilds; i++) { + DOMNode* node = node_list->item(i); + if (node->getNodeType() == DOMNode::ELEMENT_NODE) { + XMLString::transcode("TOI", tempStr, 99); + DOMAttr* pAttr = ((DOMElement *) node)->getAttributeNode(tempStr); + const XMLCh* toi_value = pAttr->getValue(); + const unsigned int toi = XMLString::parseInt(toi_value); + + if (returnedList == NULL) + returnedList = returnedListElement = this->getFileInfo(toi); + else { + returnedListElement->nextFile = this->getFileInfo(toi); + returnedListElement = returnedListElement->nextFile; + } + } + } + + + + + return returnedList; +} + + +class FluteFileInfo *FluteFDT::getFileInfo(TOI_t toi) +{ + class FluteFileInfo *NewFileInfo = NULL; + class FluteFile *temp_NewFile = NULL; + XMLCh tempStr[100]; + DOMNode* node = NULL; + unsigned int i, nchilds; + + /* first check if it isn't already included in the filelist */ + if ( (temp_NewFile = flutecb->myfiles->FFileFindTOI(toi)) != NULL) + { + return temp_NewFile->createFileInfo(); + } + + + /* I get reference to the root element of the document */ + DOMElement* root = doc->getDocumentElement(); + + XMLString::transcode("File", tempStr, 99); + DOMNodeList* node_list = root->getElementsByTagName(tempStr); + + if ((nchilds = node_list->getLength())==0) { + return NULL; + } + XMLString::transcode("TOI", tempStr, 99); + for (i = 0; i < nchilds; i++) { + DOMNode* temp_node = node_list->item(i); + DOMAttr* pAttr = ((DOMElement *) temp_node)->getAttributeNode(tempStr); + const XMLCh* toi_value = pAttr->getValue(); + if(toi==(unsigned int) XMLString::parseInt(toi_value)) + { + node = temp_node; + break; + } + } + + if (node == NULL) { + return NULL; + } + else + { + NewFileInfo = new FluteFileInfo(); + + /* Content-Location */ + XMLString::transcode("Content-Location", tempStr, 99); + DOMAttr* pAttr = ((DOMElement *) node)->getAttributeNode(tempStr); + const XMLCh* value = pAttr->getValue(); + char * temp_char = XMLString::transcode(value); + + /* Remove string file:// */ + if (XMLString::startsWith(temp_char,"file://")) + { + int len = strlen(temp_char); + strncpy(temp_char, temp_char + 7, len - 7); + temp_char[len - 7] = '\0'; + } + + /* Detect possible ':' (like c:/) and replace them with '/' */ + char *p; + if ((p = strchr(temp_char, ':')) != NULL) { + *p = '/'; + } + + strncpy(NewFileInfo->fullname,"./", 2); /* just to be sure it is copied in current directory */ + strncpy(NewFileInfo->fullname+2, temp_char, MAX_PATH+MAX_FILENAME ); + NewFileInfo->received=0; + NewFileInfo->toi = toi; + NewFileInfo->integrity =0; + NewFileInfo->nextFile = NULL; + + /* Content-Length */ + NewFileInfo->contentLength=0; + XMLString::transcode("Content-Length", tempStr, 99); + if ((pAttr = ((DOMElement *) node)->getAttributeNode(tempStr))!=NULL) + { + value = pAttr->getValue(); + NewFileInfo->contentLength = (unsigned long) XMLString::parseInt(value); + } + + /*We assume transferLength = contentLength */ + NewFileInfo->transferLength = NewFileInfo->contentLength; + + } + + return NewFileInfo; + +} + diff --git a/src/flute_lib/FluteFDT.h b/src/flute_lib/FluteFDT.h new file mode 100644 index 0000000..8fd7a63 --- /dev/null +++ b/src/flute_lib/FluteFDT.h @@ -0,0 +1,199 @@ +/* $Id: FluteFDT.h,v 1.2 2005/05/12 16:03:35 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FluteFDT_H +#define FluteFDT_H + +/* set it to 0 if FDT never expires */ +#define FDT_LIFETIME 1000000 + +XERCES_CPP_NAMESPACE_USE + +/** + * This Class handels the fdt + */ +class FluteFDT { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + * Creates the FDT + */ + FluteFDT (class flute_cb * flutecb); + + /** + * Default destructor. + * Closes and frees the FDT + */ + ~FluteFDT (); + + + /** + * Sets the Expires attribute of the FDT. + * @param ivalue character string of the timestamp value + */ + void setExpires(char * value); + + + /** + * Returns the Expires attribute of the FDT. + * @return character string of the Expires timestamp value + */ + char* getExpires(); + + /** + * Check if the timestamp passed as character string expired, + * i.e. timestamp < time_now. + * @param ivalue character string of the timestamp value + */ + void checkExpires(char * ivalue); + + + /** + * Returns the Complete attribute of the FDT. + * @return true if complete == true; else false. + */ + bool isComplete(); + + + /** + * Checks if object with a given toi is described in FDT. + * @param toi TOI of the object + * @return true if described in the FDT, else false. + */ + bool hasTOIinFDT(UINT64 toi); + + + /** + * Update the FDT. Adds elements of the FDTinstance to the FDT + * @param xmlfdtinstance pointer to the buffer containing the xml + * string of the fdt instance + * @param length len of the xml string of the fdt instance + */ + void updateFDT(char* xmlfdtinstance, unsigned int length); + + + /** + * Creates a new File Element, that may be added to the FDT + * @return the new File element + */ + XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* createNewFile(); + + + /** + * Appends a File Element to the FDT + * @param el element that has to be appended to the FDT + */ + void appendFile(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *el); + + + /** + * Sets value of an elements attribute. Attribute is created if needed. + * @param el pointer to the element + * @param name name of the attribute + * @param value value of the attribute + * @return the updated element el. + */ + XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* setAttribute(XERCES_CPP_NAMESPACE_QUALIFIER DOMElement* el, char * name, char* ivalue); + + + /** + * Gathers FTI information for a given node, and updates + * FTI_infos accordingly. + * @param nodeToCheck node where to search FTI infos + * @param FTI_infos struct that needs to be updated, containing all FTI information. + * @return true if FTI information found, false if not. + */ + bool getFTIinfos(XERCES_CPP_NAMESPACE_QUALIFIER DOMNode* nodeToCheck, FTI_infos_t * FTI_infos); + + + /** + * Creates a new (empty) FDT instance, taking the FDT as a basis. + * @return the FDT instance + */ + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* createNewFDTinstance(); + + + /** + * Adds a file to the FDT instance. + * @param fdtinstance the FDT instance + * @param itoi the toi of the file that has to added + * @return the updated FDT instance + */ + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* AddFileToFDTinstance(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* fdtinstance, unsigned int itoi); + + /** + * Creates the FDT instance xml-string. + * @param fdtinstance the FDT instance + * @param buffer outputbuffer containing the xml string, allocated by the callee + * @return length of the xml string + */ + unsigned int getFinalFDTInstance(XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* fdtinstance, char ** buffer); + + + /** + * Adds the file with the given toi of the FDT + * to the FileList and signal the selection to mclv3. + * @param filelist list of files, where new has to be added to + * @param toi toi of the file that has to be added + */ + void selectTOI(class FluteFileList *filelist, TOI_t toi); + + /** + * Adds all elements of the FDT to the FileList + * ONLY in !interactive mode. + * @param filelist file list that needs to be updated + */ + void selectAllTOIs(class FluteFileList *filelist); + + + class FluteFileInfo *getFileInfoList(); + + class FluteFileInfo *getFileInfo(TOI_t toi); + +private: + + /*local variables*/ + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* doc; + DOMImplementation *impl; + DOMBuilder* dom_builder; + + UINT64 fdt_lifetime; + class flute_cb * flutecb; + + +}; + +#endif + + + + + + + + + + + diff --git a/src/flute_lib/FluteFec.cpp b/src/flute_lib/FluteFec.cpp new file mode 100644 index 0000000..64a67bc --- /dev/null +++ b/src/flute_lib/FluteFec.cpp @@ -0,0 +1,215 @@ +/* $Id: FluteFec.cpp,v 1.2 2005/05/12 16:03:35 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "flute_includes.h" + +FluteFec::FluteFec(class flute_cb * flutecb) { + + ASSERT(flutecb->mode == SEND); + this->flutecb = flutecb; + FindAvailableFEC(); + +} + +FluteFec::~FluteFec() { +} + + +/* + * Updates the FEC available global variables depending on the available + * FEC codecs. + * Sets the FEC ratio for each possible FEC codec. + * Retrieves the maximum block size for each possible FEC codec. + */ +void FluteFec::FindAvailableFEC (void) +{ + ASSERT(flutecb->fec_ratio >= 1.0); + /* + * NULL_FEC codec first (should always be supported) + */ + RegisterFecCodec( MCL_FEC_SCHEME_NULL, + &NULL_FEC_info,"NULL", + NULL_FEC_MAX_FRAGMENT_SIZE,flutecb->fec_ratio); + + /* + * now let's see the other FEC codecs + */ + if (flutecb->fec_ratio == 1.0) { + /* user wants no FEC */ + RSE_FEC_info.available = 0; + LDGM_STAIRCASE_FEC_info.available = 0; + LDGM_TRIANGLE_FEC_info.available = 0; + } else { + /* user wants some FEC */ + /* + * RSE + */ + + RegisterFecCodec( MCL_FEC_SCHEME_RSE_129_0, + &RSE_FEC_info,"RSE", + RSE_MAX_FRAGMENT_SIZE,flutecb->fec_ratio); + + /* tests MCL blocking algo: define a large frag size */ + //RSE_FEC_info.max_fragment_size = 512*1024; + +#if defined(ALC) + /* + * LDGM STAIRCASE + */ + RegisterFecCodec(MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0, + &LDGM_STAIRCASE_FEC_info, + "LDGM STAIRCASE", + LDGM_MAX_FRAGMENT_SIZE, + flutecb->fec_ratio ); + /* + * LDGM TRIANGLE + */ + RegisterFecCodec(MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1 , + &LDGM_TRIANGLE_FEC_info , + "LDGM TRIANGLE ", + LDGM_MAX_FRAGMENT_SIZE, + flutecb->fec_ratio ); + + +#elif defined(NORM) + LDGM_STAIRCASE_FEC_info.available = 0; + LDGM_TRIANGLE_FEC_info.available = 0; +#endif /* RM_PROTOCOL */ + // Remove following tow lines comment to test with RSE + //LDGM_STAIRCASE_FEC_info.available = 0; + //LDGM_TRIANGLE_FEC_info.available = 0; + if (!RSE_FEC_info.available && !LDGM_STAIRCASE_FEC_info.available && !LDGM_TRIANGLE_FEC_info.available) { + EXIT(("Flute: ERROR, at least one of RSE or LDGM codecs must be available\n")) + } + } +} + + +/* + * Choose the most appropriate FEC codec, depending on the file size + * and the available FEC codecs. + * @param file_size file size + * @return FEC codec chosen + */ +fec_codec_info_t * +FluteFec::ChooseFEC (int file_size) +{ + int codec; + fec_codec_info_t *codec_info; + + if (flutecb->fec_ratio == 1.0) { + ASSERT(NULL_FEC_info.available); + codec = MCL_FEC_SCHEME_NULL; + codec_info = &NULL_FEC_info; + goto codec_found; + } + /* + * With ALC, use LDGM first for big files and RSE for + * small files, and if the default choice is not available, + * use the other one. + */ + if (file_size >= RSE_LDGM_FILE_SIZE_THRESHOLD) { + if (flutecb->fec_ratio >= 2.5 && LDGM_STAIRCASE_FEC_info.available) { + /* + * Use LDGM Staircase with large FEC expansion ratios. + */ + codec = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0; + codec_info = &LDGM_STAIRCASE_FEC_info; + } else if (LDGM_TRIANGLE_FEC_info.available) { + /* + * Use LDGM Triangle with small FEC expansion ratios. + */ + codec = MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1; + codec_info = &LDGM_TRIANGLE_FEC_info; + } else { + ASSERT(RSE_FEC_info.available) + codec = MCL_FEC_SCHEME_RSE_129_0; + codec_info = &RSE_FEC_info; + } + } else { + if (RSE_FEC_info.available) { + codec = MCL_FEC_SCHEME_RSE_129_0; + codec_info = &RSE_FEC_info; + } else { + ASSERT(LDGM_STAIRCASE_FEC_info.available) + codec = MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0; + codec_info = &LDGM_STAIRCASE_FEC_info; + } + } + +codec_found: + /* set the codec now */ + if (mcl_ctl(flutecb->id, MCL_OPT_SET_FEC_CODE, (void*)&codec, sizeof(codec))) { + EXIT(("Flute: ERROR, ctl for MCL_OPT_SET_FEC_CODE (%d) failed\n", codec)) + } + return codec_info; +} + + +#if 0 +/* + * Determines the optimum file segmentation, and the appropriate FEC codec + * to use. + * @param + * @return + */ +int +FluteFec::FileSegmentation +{ +} +#endif + + + +void FluteFec::RegisterFecCodec(int codec, + fec_codec_info_t *codec_info , + char * codec_string, + unsigned int max_fragment_size, + float fec_ratio){ + + int max_sz; + if (mcl_ctl(flutecb->id, MCL_OPT_SET_FEC_CODE, (void*)&codec, + sizeof(codec))) { + codec_info->available = 0; + }else { + codec_info->available = 1; + if (mcl_ctl(flutecb->id, MCL_OPT_FEC_RATIO, (void*)&fec_ratio, + sizeof(fec_ratio))) + EXIT(("Flute: ERROR, mcl_ctl failed for FEC_RATIO %f for %s codec\n", fec_ratio,codec_string)); + /* + * determine the max block size, as defined by MCL, + * and the associated max file fragment size, used + * by FCAST. + */ + if (mcl_ctl(flutecb->id, + MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC, + (void*)&max_sz, sizeof(max_sz))) { + EXIT(("Flute: ERROR, mcl_ctl failed for MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC for %s codec\n",codec_string)); + } + codec_info->max_block_size = max_sz; + codec_info->max_fragment_size = min(LDGM_MAX_FRAGMENT_SIZE, max_sz); + } +} + + + diff --git a/src/flute_lib/FluteFec.h b/src/flute_lib/FluteFec.h new file mode 100644 index 0000000..11a5ab3 --- /dev/null +++ b/src/flute_lib/FluteFec.h @@ -0,0 +1,96 @@ +/* $Id: FluteFec.h,v 1.2 2005/05/12 16:03:35 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_FEC_H +#define FLUTE_FEC_H + + + +/* available FEC codecs and associated information */ +typedef struct fec_codec_info { + int available; /* boolean */ + int max_block_size; /* raw value as defined by MCL */ + int max_fragment_size; /* big files are fragmented into */ + /* fragments of this size */ +} fec_codec_info_t; + + +class FluteFec { + +public: + +FluteFec::FluteFec(class flute_cb * flutecb); + +FluteFec::~FluteFec(); + +/* + * Updates the FEC available global variables depending on the available + * FEC codecs. + * Sets the FEC ratio for each possible FEC codec. + * Retrieves the maximum block size for each possible FEC codec. + */ +void FindAvailableFEC (void); + + +/** + * RegisterFecCodec: lookup with mcl if the codec "codec" is available, + * if it is available then fill the codec_info fields max_block_size, and + * max_fragment size else "codec_info->avalable" is set to 0 + * + * @param codec the codec to register + * @param codec_info the fec_codec_info_t struct to fill + * @param codec_string a string of the mùane of the codec ( for possible error message) + * @param max_fragment_size the max framgent size of the codec + * @param fec_ratio fec_ratio to use the codec with + */ + +void RegisterFecCodec(int codec, + fec_codec_info_t *codec_info , + char * codec_string, + unsigned int max_fragment_size, + float fec_ratio); + + +/* + * Choose the most appropriate FEC codec, depending on the file size + * and the available FEC codecs. + * @param file_size file size + * @return FEC codec chosen + */ +fec_codec_info_t * ChooseFEC (int file_size); + + +/* The possibles codecs */ + +fec_codec_info_t NULL_FEC_info; +fec_codec_info_t RSE_FEC_info; +fec_codec_info_t LDGM_STAIRCASE_FEC_info; +fec_codec_info_t LDGM_TRIANGLE_FEC_info; + +private: + + class flute_cb *flutecb; + +}; + + +#endif diff --git a/src/flute_lib/FluteFile.cpp b/src/flute_lib/FluteFile.cpp new file mode 100644 index 0000000..0199135 --- /dev/null +++ b/src/flute_lib/FluteFile.cpp @@ -0,0 +1,72 @@ +/* $Id: FluteFile.cpp,v 1.2 2005/05/12 16:03:36 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "flute_includes.h" + + +FluteFile::FluteFile(class flute_cb * flutecb) { + this->flutecb = flutecb; +} + +FluteFile::~FluteFile() { + + close(fd); + +} + +#ifdef OPENSSL +INT32 FluteFile::FFilemd5sum_check() { + + unsigned char * digest = (unsigned char*)calloc(1,MD5BASE64_LENGTH); + int temp_fd=open(this->fullname, O_RDONLY); + md5sum_calculate(temp_fd, &digest); + close(temp_fd); + + if (strncmp((const char*)digest,(const char*) this->md5sum, MD5BASE64_LENGTH)==0) return 1; + + return 0; + +} +#endif + +class FluteFileInfo *FluteFile::createFileInfo() { + + class FluteFileInfo *NewFile = new FluteFileInfo(); + + mcl_adu_rx_info_t rx_info; /* struct containing ADU reception info */ + rx_info.toi = this->toi; + if (mcl_ctl(this->flutecb->id, MCL_OPT_GET_ADU_RX_INFO, (void*)&rx_info, sizeof(rx_info)) == 0) { + NewFile->bytesReceived = rx_info.recvd_src_data; + } + strncpy(NewFile->fullname, this->fullname, MAX_PATH+MAX_FILENAME ); + NewFile->received = this->received; + NewFile->selected = this->selected; + NewFile->toi = this->toi; + NewFile->integrity = this->integrity; + NewFile->contentLength = this->contentLength; + NewFile->transferLength = this->transferLength; + NewFile->nextFile = NULL; + + + return NewFile; + +} diff --git a/src/flute_lib/FluteFile.h b/src/flute_lib/FluteFile.h new file mode 100644 index 0000000..30997fb --- /dev/null +++ b/src/flute_lib/FluteFile.h @@ -0,0 +1,212 @@ +/* $Id: FluteFile.h,v 1.2 2005/05/12 16:03:36 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_FILE_H +#define FLUTE_FILE_H + +#ifdef WIN32 +#include +#endif + +class FluteFile : FluteFileInfo { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + FluteFile (class flute_cb * flutecb); + + /** + * Default destructor. + */ + ~FluteFile (); + + class FluteFileInfo *createFileInfo(); + +#ifdef OPENSSL + INT32 FFilemd5sum_check(); +#endif + + /********* variables ****************/ + + + INT32 fd; // File descriptor + INT32 writeIt; // Shall we write it or not? + // In some cases it means overwritting + // an existing file. + unsigned char md5sum[MD5BASE64_LENGTH];// MD5sum (in BASE64) indicated by FDT + + FluteFile * nextFile; // pointer to the next File (if any). + + friend class FluteFDT; + friend class FluteFileList; + friend class FluteReceiver; + + + /******** static functions ***********/ + static int FileExist( const char *filepath) + { + FILE *check; + check = fopen(filepath, "r"); + + ASSERT(filepath!=NULL); + + if( check == NULL) + return 0; + else + { + fclose(check); + return 1; + } + } + + + + static int IsDirDots (const char *path) + { + return (path[0] == '\0' + || (path[0] == '.' && (path[1] == '\0' + || (path[1] == '.' && path[2] == '\0')))); + } + + static void GetFileBase( char *filepath, char *filebase ) + { + char *token1, *token2; + + ASSERT( (filepath != NULL) + && (filebase != NULL) + && (strlen(filepath)<=(MAX_PATH+MAX_FILENAME)) ) + + token1 = filepath; + token2 = strpbrk(token1, "/\\"); + while( token2 ) + { + token1 = token2+1; + token2 = strpbrk(token1, "/\\"); + } + if(token1 == filepath) + strcpy(filebase, "./"); + else + { + strncpy(filebase, filepath, (strlen(filepath)-strlen(token1))); + filebase[strlen(filepath)-strlen(token1)] = '\0'; + } + + } + + static int CheckWriteContext( class flute_cb *flutecb, char *filepath, int mode) + { + int writeIt = 0; + + if( FluteFile::FileExist(filepath) ) + { + char c = '\0'; + switch (mode) + { + case ALWAYS: + writeIt = 1; + break; + case NEVER: + writeIt = 0; + break; + case PROMPT: + read: + PRINT(("\nFile \"%s\" exists, overwrite? [y/n] ", filepath)) + fflush(stdin); + scanf("%c", &c); + if(c == 'y') + writeIt = 1; + else if(c == 'n') + writeIt = 0; + else + goto read; + break; + default: + PRINT(("CheckWriteContext: ERROR, Unknown overwrite mode")) + writeIt = 0; + break; + } + } + else + { + struct stat stats; + char *DirName_buf; + char *DirName; + char *Prefix_buf; + char *Prefix; + + if (!(DirName_buf = DirName = (char*)malloc(MAX_PATH)) || + !(Prefix_buf = Prefix = (char*)malloc(MAX_PATH))) { + PRINT(("CheckWriteContext: ERROR, No Memory")) + exit(1); + } + GetFileBase(filepath, DirName); + if(DirName[0] == '/' || DirName[0] == '\\') + strcpy(Prefix, "\0"); + else + strcpy(Prefix, ".\0"); + + DirName = strtok( DirName, "/\\"); + while( DirName ) + { + strcat(Prefix, "/"); + strcat(Prefix, DirName); + if(stat(Prefix, &stats) != -1) + { + if( !(stats.st_mode & S_IFDIR )) + { + PRINT(("Unable to create directory %s, because a file with the same name already exists\n", Prefix)) + goto end; + } + } + else + { + PRINT(("Creating directory %s\n", Prefix)) +#ifdef WIN32 + if(mkdir( Prefix ) <0 ) +#else + if(mkdir( Prefix, 0755) <0 ) +#endif + { + EXIT(("%s : Unable to create directory\n", Prefix)) + } + } + DirName = strtok( NULL, "/\\"); + } + free(DirName_buf); + free(Prefix_buf); + writeIt = 1; + } + + end: return writeIt; + } + + + +private: + /************* private members ******/ + class flute_cb* flutecb; + +}; + +#endif diff --git a/src/flute_lib/FluteFileDeliveryCarousel.cpp b/src/flute_lib/FluteFileDeliveryCarousel.cpp new file mode 100644 index 0000000..d9f993d --- /dev/null +++ b/src/flute_lib/FluteFileDeliveryCarousel.cpp @@ -0,0 +1,469 @@ +/* $Id: FluteFileDeliveryCarousel.cpp,v 1.3 2005/05/13 15:49:51 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include "flute_includes.h" + +/** + * FluteFileDeliveryCarousel constructor + */ +FluteFileDeliveryCarousel::FluteFileDeliveryCarousel(class FluteSender *flute) { + + this->flute = flute; + this->flutecb = flute->flutecb; + + if(mcl_ctl(flutecb->id, MCL_OPT_KEEP_DATA, NULL, 0)) + EXIT(("Flute: mcl_ctl KEEP_DATA failed\n")) + + this->mode = READY; + this->BytesSent = 0; + this->endOfTxCycles_callback = NULL; + +} + +/** + * FluteFileDeliveryCarousel destructor + */ +FluteFileDeliveryCarousel::~FluteFileDeliveryCarousel() { +} + + +/** + * Reset the carousel: + * - stop tx if carousel is in transmission + * - remove all files scheduled for transmission + */ +void FluteFileDeliveryCarousel::reset() { + + /* TODO: reset the queued files have not been transmitted yet + */ + + flutecb->lock(); + + if (this->mode == IN_TX) + { + if(mcl_ctl(flutecb->id, MCL_OPT_RESET_TRANSMISSIONS, NULL, 0)) + EXIT(("Flute: mcl_ctl MCL_OPT_RESET_TRANSMISSIONS failed\n")) + + if(mcl_ctl(flutecb->id, MCL_OPT_KEEP_DATA, NULL, 0)) + EXIT(("Flute: mcl_ctl KEEP_DATA failed\n")) + } + flutecb->unlock(); + +} + +/** + * Sets the Callback function called when transmission is over. + * @param EndOfTxCycles_callback Callback function, having the number + * of transmitted bytes as parameter. + */ +void FluteFileDeliveryCarousel::setCallbackEndOfTxCycles(void* (*EndOfTxCycles_callback)(UINT64 BytesSent)) { + + flutecb->lock(); + this->endOfTxCycles_callback = EndOfTxCycles_callback; + + flutecb->unlock(); +} + +/** + * Add file to be scheduled for transmission + * @param filename name of the file + * @return toi affected to the file + */ +TOI_t FluteFileDeliveryCarousel::addFile(char *filename) { + + + TOI_t result = 0; + struct stat file_stats; + int file_to_send = 0; + struct mcl_iovec iov; /* for mcl_sendmsg */ + struct mcl_msghdr msg; /* for mcl_sendmsg */ +#define TEMP_STRING_LEN 128 + char *temp_string; + UINT64 len; +#ifdef OPENSSL + unsigned char *md5sum; +#endif + XERCES_CPP_NAMESPACE_QUALIFIER DOMElement *el; + + flutecb->lock(); + + if (flutecb->initialized == false) + { + + /* finish initializing */ + flute->init(); + + } + + if (flutecb->fdtinstance == NULL) { + /* create an fdt instance */ + flutecb->fdtinstance = flutecb->fdt->createNewFDTinstance(); + } + + /* allocate temp string for fdt instance attribute construction */ + if ((temp_string = (char*)malloc(TEMP_STRING_LEN)) == NULL) { + EXIT(("Flute: SendThisFile: Error, malloc failed\n")) + } + + + /* + * Set the TOI for this file + */ + flutecb->toiindex++; + if (mcl_ctl(flutecb->id, MCL_OPT_SET_NEXT_TOI, (void*)&flutecb->toiindex, + sizeof(flutecb->toiindex))) + EXIT(("Flute: mcl_ctl MCL_OPT_SET_NEXT_TOI failed\n")) + + + if (FluteFile::FileExist(filename)) { + if (stat(filename, &file_stats) == -1) { + EXIT(("Flute: SendThisFile: Error: stat()\n")) + } +#ifdef WIN32 + file_to_send = open(filename, O_RDONLY | O_BINARY); +#else + file_to_send = open(filename, O_RDONLY); +#endif + if (file_to_send < 0) { + EXIT(("Flute: open failed for file %s\n", filename)) + } + } else { + PRINT(("Flute: SendThisFile: Error: %s, no such file!\n", filename)) + goto end; + } + if (!(file_stats.st_mode & S_IFREG)) + EXIT(("Flute: SendThisFile: Error: %s is not a regular file\n", filename)) + + flutecb->fec->ChooseFEC(file_stats.st_size); + + /* + * create a corresponding msg descriptor. + */ + memset((void*)&iov, 0, sizeof(iov)); + memset((void*)&msg, 0, sizeof(msg)); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + iov.iov_type = MCL_IOV_TYPE_FILE; + iov.iov_filename = filename; + iov.iov_len = file_stats.st_size; + if (mcl_sendmsg(flutecb->id, &msg, MCL_MSG_DEFAULT) < 0) + EXIT(("Flute: SendThisFile: mcl_sendmsg failed\n")) + this->BytesSent += file_stats.st_size; + + /* + * Update the FDT now... + */ + el = flutecb->fdt->createNewFile(); + + /*TOI*/ +#ifdef WIN32 + len = sprintf(temp_string, "%u", flutecb->toiindex); +#else + len = snprintf(temp_string, TEMP_STRING_LEN, "%u", flutecb->toiindex); +#endif + if (len < 0 || len >= TEMP_STRING_LEN) { + EXIT(("Flute: SendThisFile: snprintf failed, returned %llu)\n", len)) + } + el = flutecb->fdt->setAttribute(el, "TOI", temp_string); + + /*Content-Location*/ + el = flutecb->fdt->setAttribute(el, "Content-Location", filename); + + /*Content-Length*/ +#ifdef WIN32 + len = sprintf(temp_string, "%lu", file_stats.st_size); +#else + len = snprintf(temp_string, TEMP_STRING_LEN, "%lu", file_stats.st_size); +#endif + if (len < 0 || len >= TEMP_STRING_LEN) { + EXIT(("Flute: SendThisFile: snprintf failed, returned %llu)\n", len)) + } + el=flutecb->fdt->setAttribute(el, "Content-Length", temp_string); + +#ifdef OPENSSL + /*Content-MD5*/ + if ((md5sum = (unsigned char*)calloc(1, MD5BASE64_LENGTH)) == NULL) { + EXIT(("Flute: SendThisFile: Error, calloc failed")) + } + md5sum_calculate(file_to_send, &md5sum); + el = flutecb->fdt->setAttribute(el, "Content-MD5", (char *)md5sum); + free(md5sum); +#endif + + flutecb->fdt->appendFile(el); + + /* Adding to fdt-instance*/ + flutecb->fdt->AddFileToFDTinstance(flutecb->fdtinstance, flutecb->toiindex); + + close(file_to_send); + + if (this->mode == IN_TX) { + + /* + * ...and the associated FDT. + */ + char *fdtbuffer; + int fdtsize = 0; + int mcl_option_toi = 0; // set TOI to 0 for the FDT + + /*fdtbuffer is allocated in getFinalFDTInstance*/ + fdtsize = flutecb->fdt->getFinalFDTInstance(flutecb->fdtinstance, &fdtbuffer); + if (mcl_ctl(flutecb->id, MCL_OPT_SET_NEXT_TOI, (void*)&mcl_option_toi, + sizeof(mcl_option_toi))) { + EXIT(("Flute: mcl_ctl MCL_OPT_SET_NEXT_TOI failed\n")) + } + if (mcl_ctl(flutecb->id, MCL_OPT_SET_NEXT_ADU_HIGH_IMPORTANCE, (void*)NULL, 0)) { + EXIT(("Flute: mcl_ctl MCL_OPT_SET_NEXT_TOI failed\n")) + } + /* Now flush high priority objects, to be sure that the FDT instance + will be sent entirely before all the ojects it is describing */ + if (mcl_ctl(flutecb->id, MCL_OPT_FLUSH_HIGH_IMPORTANCE_OBJECTS, (void*)NULL, 0)) { + EXIT(("Flute: mcl_ctl MCL_OPT_FLUSH_HIGH_IMPORTANCE_OBJECTS failed\n")) + } + + flutecb->fec->ChooseFEC(fdtsize); + + if (mcl_send(flutecb->id, fdtbuffer , fdtsize) < 0) + EXIT(("Flute: mcl_send failed\n")) + + if (fdtbuffer!= NULL) free(fdtbuffer); + flutecb->fdtinstance->release(); + flutecb->fdtinstance = NULL; + + } + + free(temp_string); + +end: + result = flutecb->toiindex; + flutecb->unlock(); + return result; +} + + +/** + * Remove file from transmission schedule. + * @param toi toi of the files that has to be removed + */ +void FluteFileDeliveryCarousel::removeFile(TOI_t toi) { + + flutecb->lock(); + + /* TODO: remove files that haven't been transmitted yet. + */ + + if (this->mode == IN_TX) { + if (mcl_ctl(flutecb->id, MCL_OPT_STOP_TRANSMITTING_ADU, (void *)&toi, sizeof(toi))) + EXIT(("Flute: mcl_ctl MCL_OPT_STOP_TRANSMITTING_ADU failed toi %ul\n", toi)) + } + flutecb->unlock(); + +} + + +/** + * Start a new transmission cycle, indicating the number of cycles. + * Can be called either in blocking (wait until the end of transmission + * in that case) or non blocking mode; + * @param nb_cycles number of transmission cycles, or CONTINUOUS + * @param blocking call as blocking or not + * @return number of transmitted bytes. + */ +UINT64 FluteFileDeliveryCarousel::startTxCycles(INT32 nb_cycles, bool blocking) { + + UINT64 result = 0; + + flutecb->lock(); + + flutecb->nb_tx = nb_cycles; + if (flutecb->nb_tx == CONTINUOUS) + { + flutecb->delivery_mode = DEL_MODE_ON_DEMAND; + } + else if (flutecb->nb_tx > 0) + { + flutecb->delivery_mode = DEL_MODE_PUSH; + if (flutecb->nb_tx >= 1) { + if( mcl_ctl(flutecb->id, MCL_OPT_NB_OF_TX, (void*)&nb_cycles, + sizeof(nb_cycles))) + EXIT(("Flute: ERROR, mcl_ctl failed for NB_OF_TX\n")) + } + + } + else + EXIT(("Flute: ERROR, non valid number of Tx cycles %i\n",nb_cycles)) + + if(mcl_ctl(flutecb->id, MCL_OPT_DELIVERY_MODE, (void*)&flutecb->delivery_mode, + sizeof(flutecb->delivery_mode))) + EXIT(("Flute: ERROR, mcl_ctl failed for DELIVERY_MODE\n")) + + + /* + * ...and the associated FDT. + */ + if (flutecb->fdtinstance != NULL) + { + char *fdtbuffer; + int fdtsize = 0; + int mcl_option_toi = 0; // set TOI to 0 for the FDT + + /*fdtbuffer is allocated in getFinalFDTInstance*/ + fdtsize = flutecb->fdt->getFinalFDTInstance(flutecb->fdtinstance, &fdtbuffer); + if (mcl_ctl(flutecb->id, MCL_OPT_SET_NEXT_TOI, (void*)&mcl_option_toi, + sizeof(mcl_option_toi))) { + EXIT(("Flute: mcl_ctl MCL_OPT_SET_NEXT_TOI failed\n")) + } + if (mcl_ctl(flutecb->id, MCL_OPT_SET_NEXT_ADU_HIGH_IMPORTANCE, (void*)NULL, 0)) { + EXIT(("Flute: mcl_ctl MCL_OPT_SET_NEXT_TOI failed\n")) + } + /* Now flush high priority objects, to be sure that the FDT instance + will be sent entirely before all the ojects it is describing */ + if (mcl_ctl(flutecb->id, MCL_OPT_FLUSH_HIGH_IMPORTANCE_OBJECTS, (void*)NULL, 0)) { + EXIT(("Flute: mcl_ctl MCL_OPT_FLUSH_HIGH_IMPORTANCE_OBJECTS failed\n")) + } + + flutecb->fec->ChooseFEC(fdtsize); + + if (mcl_send(flutecb->id, fdtbuffer , fdtsize) < 0) + EXIT(("Flute: mcl_send failed\n")) + + if (fdtbuffer!= NULL) free(fdtbuffer); + flutecb->fdtinstance->release(); + flutecb->fdtinstance = NULL; + } + + if(mcl_ctl(flutecb->id, MCL_OPT_PUSH_DATA, NULL, 0)) + EXIT(("Flute: mcl_ctl PUSH_DATA failed\n")) + + this->mode = IN_TX; + + if (blocking == true) { + + flutecb->unlock(); + this->waitTx((void *) NULL); + flutecb->lock(); + + } + else if (blocking == false) { + flutecb->unlock(); +#ifdef WIN32 + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) this->waitTx((void *) NULL), (void*)NULL, 0, (LPDWORD)&send_thread); +#else + pthread_create(&send_thread, NULL, (void*(*)(void*)) this->waitTx((void *) NULL), (void *)NULL); + pthread_detach(send_thread); +#endif + flutecb->lock(); + } + + result = BytesSent; + flutecb->unlock(); + + return result; + + +} + + + +/** + * Add new transmission cycles to an ongoing carousel. + * @param nb_cycles number of transmission cycles, or CONTINUOUS + */ +void FluteFileDeliveryCarousel::addTxCycles(INT32 nb_cycles) { + + flutecb->lock(); + + if (nb_cycles == CONTINUOUS) + { + flutecb->nb_tx = nb_cycles; + flutecb->delivery_mode = DEL_MODE_ON_DEMAND; + } + else if (nb_cycles > 0) + { + flutecb->delivery_mode = DEL_MODE_PUSH; + + flutecb->nb_tx += nb_cycles; + if (flutecb->nb_tx >= 1) { + if( mcl_ctl(flutecb->id, MCL_OPT_ADD_NB_OF_TX, (void*)&nb_cycles, + sizeof(nb_cycles))) + EXIT(("Flute: ERROR, mcl_ctl failed for NB_OF_TX\n")) + } + + } + else + EXIT(("Flute: ERROR, non valid number of Tx cycles %i\n",nb_cycles)) + + if(mcl_ctl(flutecb->id, MCL_OPT_DELIVERY_MODE, (void*)&flutecb->delivery_mode, + sizeof(flutecb->delivery_mode))) + EXIT(("Flute: ERROR, mcl_ctl failed for DELIVERY_MODE\n")) + + flutecb->unlock(); + +} + +/** + * Stop an ongoing transmission carousel. + * @return number of transmitted bytes + */ +UINT64 FluteFileDeliveryCarousel::stopTx() { + + flutecb->lock(); + + if (this->mode == IN_TX) + { + if(mcl_ctl(flutecb->id, MCL_OPT_RESET_TRANSMISSIONS, NULL, 0)) + EXIT(("Flute: mcl_ctl MCL_OPT_RESET_TRANSMISSIONS failed\n")) + + if(mcl_ctl(flutecb->id, MCL_OPT_KEEP_DATA, NULL, 0)) + EXIT(("Flute: mcl_ctl KEEP_DATA failed\n")) + } + + flutecb->unlock(); + + return BytesSent; + +} + + +/** + * Flute transmission function (either called as a seperate thread + * (non-blocking) or within the Flute-thread (blocking)). + * @param arg required for threads. + */ +void *FluteFileDeliveryCarousel::waitTx(void * arg) { + + if (mcl_wait_event(flutecb->id, MCL_WAIT_EVENT_END_TX) == -1) + EXIT(("Flute: mcl_wait_event MCL_WAIT_EVENT_END_TX failed\n")) + + flutecb->lock(); + + if (this->endOfTxCycles_callback != NULL) { + + UINT64 val = this->BytesSent; + flutecb->unlock(); + this->endOfTxCycles_callback(val); + flutecb->lock(); + } + + flutecb->unlock(); +} diff --git a/src/flute_lib/FluteFileDeliveryCarousel.h b/src/flute_lib/FluteFileDeliveryCarousel.h new file mode 100644 index 0000000..940b6f4 --- /dev/null +++ b/src/flute_lib/FluteFileDeliveryCarousel.h @@ -0,0 +1,71 @@ +/* $Id: FluteFileDeliveryCarousel.h,v 1.2 2005/05/12 16:03:37 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_FILE_DELIVERY_CAROUSEL_H +#define FLUTE_FILE_DELIVERY_CAROUSEL_H + + +class FluteFileDeliveryCarousel { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + FluteFileDeliveryCarousel (class FluteSender *flute); + + /** + * Default destructor. + */ + ~FluteFileDeliveryCarousel (); + + void reset(); + + TOI_t addFile(char* filename); + + void removeFile(TOI_t toi); + + UINT64 startTxCycles(INT32 nb_cycles, bool blocking); + + void addTxCycles(INT32 nb_cycles); + + UINT64 stopTx(); + + void setCallbackEndOfTxCycles(void* (*EndOfTxCycles_callback)(UINT64 BytesSent)); + +private: + + UINT64 BytesSent; + + void* waitTx(void * arg); + void* (*endOfTxCycles_callback)(UINT64 BytesSent); + + flute_thread_t send_thread; + + int mode; + + class flute_cb * flutecb; + class FluteSender * flute; + +}; + +#endif diff --git a/src/flute_lib/FluteFileInfo.cpp b/src/flute_lib/FluteFileInfo.cpp new file mode 100644 index 0000000..5588965 --- /dev/null +++ b/src/flute_lib/FluteFileInfo.cpp @@ -0,0 +1,144 @@ +/* $Id: FluteFileInfo.cpp,v 1.3 2005/05/13 15:49:51 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "flute_includes.h" + + +/** + * FluteFileInfo constructor + */ +FluteFileInfo::FluteFileInfo (){ + + this->nextFile = NULL; + this->bytesReceived = 0; +} + +/** + * FluteFileInfo destructor + */ +FluteFileInfo::~FluteFileInfo (){ +} + +/** + * Get the next file in the list. + * @return next fileInfo in the list. + */ +FluteFileInfo * FluteFileInfo::getNextFile(){ + + return this->nextFile; + +} + +/** + * Get the file name. + * @param filename (OUT) file name + * @param len (OUT) length of the string of the file name + */ + +void FluteFileInfo::getFilename(char ** filename, int* len) { + + *filename = fullname; + *len = MAX_PATH+MAX_FILENAME; + +} + +/** + * Get the TOI of the file + * @return TOI of the file. + */ +TOI_t FluteFileInfo::getTOI() { + + return this->toi; + +} + + +/** + * Get the MIME type of the file + * @param type (OUT) mime type (string) + * @param len (OUT) length of the string of the mime type + */ +void FluteFileInfo::getMIMEType(char ** type, int* len) { + /* TODO */ +} + + +/** + * Get the number of bytes received for that file + * @return number of bytes received. + */ +UINT64 FluteFileInfo::getBytesRcvd() { + + return bytesReceived; + +} + +/** + * Get the transfer length. + * @return transfer length. + */ +UINT64 FluteFileInfo::getTransferLength() { + + return transferLength; + +} + +/** + * Get the content length. + * @return content length. + */ +UINT64 FluteFileInfo::getContentLength() { + + return contentLength; + +} + +/** + * Has the file been received entirly? Yes/No + * @return true or false. + */ +bool FluteFileInfo::getReceived() { + + return received; + +} + + +/** + * Has the file been selected for reception? Yes/No + * @return true or false. + */ +bool FluteFileInfo::isSelected() { + + return selected; + +} + +/** was md5sum check sucessfull or not? + * (-1 fail, 0 no information, 1 check ok) + * @return -1 fail, 0 no information, 1 check ok + */ +int FluteFileInfo::getIntegrity() { + + return integrity; + +} diff --git a/src/flute_lib/FluteFileInfo.h b/src/flute_lib/FluteFileInfo.h new file mode 100644 index 0000000..f47091e --- /dev/null +++ b/src/flute_lib/FluteFileInfo.h @@ -0,0 +1,84 @@ +/* $Id: FluteFileInfo.h,v 1.2 2005/05/12 16:03:37 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_FILE_INFO_H +#define FLUTE_FILE_INFO_H + + +class FluteFileInfo { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + FluteFileInfo (); + + /** + * Default destructor. + */ + ~FluteFileInfo (); + + FluteFileInfo* getNextFile(); + + void getFilename(char ** filename, int* len); + + TOI_t getTOI(); + + void getMIMEType(char ** type, int* len); + + UINT64 getBytesRcvd(); + + UINT64 getTransferLength(); + + UINT64 getContentLength(); + + bool getReceived(); + + INT32 getIntegrity(); + + bool isSelected(); + +protected: + + FluteFileInfo * nextFile; // pointer to the next File (if any). + + char fullname[MAX_PATH+MAX_FILENAME]; // Full path+name + + TOI_t toi; //toi of the file + + UINT64 contentLength; + UINT64 transferLength; + UINT64 bytesReceived; + + bool received; // got the file?? + bool selected; + + INT32 integrity; // was md5sum check sucessfull or not? + // (-1 fail, 0 no information, 1 check ok) + + friend class FluteFile; + friend class FluteFDT; + +}; + +#endif diff --git a/src/flute_lib/FluteFileList.cpp b/src/flute_lib/FluteFileList.cpp new file mode 100644 index 0000000..68e3ed6 --- /dev/null +++ b/src/flute_lib/FluteFileList.cpp @@ -0,0 +1,162 @@ +/* $Id: FluteFileList.cpp,v 1.2 2005/05/12 16:03:38 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "flute_includes.h" + + +FluteFileList::FluteFileList (class flute_cb *flutecb) { + + this->flutecb = flutecb; + this->head = NULL; + +} + +FluteFileList::~FluteFileList () { + + FluteFile *temp; + + /* free the list */ + while(this->head != NULL) { + + temp = this->head; + this->head = this->head->nextFile; + delete temp; + } + +} + + +void FluteFileList::FFileInsert(FluteFile *newfile) { + + FluteFile *list = this->head; + + if (list == NULL) { + + this->head = newfile; + } + else + { + while (list->nextFile != NULL) { + list = list->nextFile; + } + list->nextFile = newfile; + } + +} + +FluteFile *FluteFileList::FFileFind ( const char *fullname) { + + FluteFile * found = NULL; + FluteFile * listloop = this->head; + + while(listloop != NULL) + { + if( !strcmp(listloop->fullname, fullname) ) { + found = listloop; + break; + } + listloop = listloop->nextFile; + } + return found; + +} + +FluteFile *FluteFileList::FFileFindTOI ( TOI_t toi ) { + + FluteFile * found = NULL; + FluteFile * listloop = this->head; + + while(listloop != NULL) + { + if(listloop->toi==toi) { + found = listloop; + break; + } + listloop = listloop->nextFile; + } + return found; + +} + +void FluteFileList::FFileRemove (const char *fullname) { + + + FluteFile * found = this->FFileFind(fullname); + FluteFile * listloop = this->head; + + if (found != NULL && listloop != NULL) + { + if(listloop == found) + { + this->head = listloop->nextFile; + delete listloop; + } + else + { + while(listloop->nextFile != found) + { + listloop = listloop->nextFile; + } + + listloop->nextFile = found->nextFile; + delete found; + } + } + else + { + EXIT(("Error: FFile %s not found!\n", fullname)) + } + + +} + + +void FluteFileList::FFileRemoveTOI (TOI_t toi) { + + FluteFile * found = this->FFileFindTOI(toi); + FluteFile * listloop = this->head; + + if (found != NULL && listloop != NULL) + { + if(listloop == found) + { + this->head = listloop->nextFile; + delete listloop; + } + else + { + while(listloop->nextFile != found) + { + listloop = listloop->nextFile; + } + + listloop->nextFile = found->nextFile; + delete found; + } + } + else + { + EXIT(("Error: FFile TOI %lu not found!\n", toi)) + } + + +} diff --git a/src/flute_lib/FluteFileList.h b/src/flute_lib/FluteFileList.h new file mode 100644 index 0000000..d51876c --- /dev/null +++ b/src/flute_lib/FluteFileList.h @@ -0,0 +1,53 @@ +/* $Id: FluteFileList.h,v 1.2 2005/05/12 16:03:38 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_FILE_LIST_H +#define FLUTE_FILE_LIST_H + +class FluteFileList { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + FluteFileList (class flute_cb *flutecb); + + /** + * Default destructor. + */ + ~FluteFileList (); + + void FFileInsert(FluteFile *newfile); + FluteFile *FFileFind ( const char *fullname); + FluteFile *FFileFindTOI ( TOI_t toi ); + void FFileRemove (const char *fullname); + void FFileRemoveTOI ( TOI_t toi); + +private: + + class FluteFile * head; + class flute_cb * flutecb; + +}; + +#endif diff --git a/src/flute_lib/FluteReceiver.cpp b/src/flute_lib/FluteReceiver.cpp new file mode 100644 index 0000000..2ed59a8 --- /dev/null +++ b/src/flute_lib/FluteReceiver.cpp @@ -0,0 +1,375 @@ +/* $Id: FluteReceiver.cpp,v 1.5 2005/05/24 09:56:15 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "flute_includes.h" + +/** + * FluteReceiver constructor + */ +FluteReceiver::FluteReceiver () { + + if ((flutecb->id = mcl_open("r")) < 0) + EXIT(("FluteSender: ERROR, mcl_open(w) failed\n")) + + flutecb->mode = RECV; + this->BytesReceived = 0; + this->endOfRx_callback = NULL; + this->receivedNewFileDescription_callback = NULL; + +} + +/** + * FluteReceiver destructor + */ +FluteReceiver::~FluteReceiver () { +} + +/** + * Sets the Callback function called when reception is over. + * @param EndOfRx_callback Callback function, having the number + * of received bytes as parameter. + */ +void FluteReceiver::setCallbackEndOfRx ( void* (*EndOfRx_callback)(UINT64 BytesRecvd)){ + + this->endOfRx_callback = EndOfRx_callback; + +} + +/** + * Sets the Callback function called when new file + * description is available. + * @param EndOfRx_callback Callback function, having the + * file descirptions as parameter + */ +void FluteReceiver::setCallbackReceivedNewFileDescription (void* (*ReceivedNewFileDescription_callback) (class FluteFileInfo * fileInfo)) { + + this->receivedNewFileDescription_callback = ReceivedNewFileDescription_callback; + +} + +/** + * Start receiving on the current Flute session. + * Can be called in blocking or non-blocking mode. + * @param blocking call as blocking or not + * @return number of bytes received + */ +UINT64 FluteReceiver::recv(bool blocking){ + + UINT64 result; + int mcl_option; + + flutecb->lock(); + + if (flutecb->initialized == false) + { + /* finish initializing */ + this->init(); + } + + if (flutecb->storeAllAdu == true) { + mcl_option = 1; + } else { + mcl_option = 0; + } + if (mcl_ctl(flutecb->id, MCL_OPT_SET_FLUTE_STORE_ALL_ADUS_BY_DEFAULT, + (void*)&mcl_option, sizeof(mcl_option))) { + EXIT(("mcl_ctl: MCL_OPT_SET_FLUTE_STORE_ALL_ADUS_BY_DEFAULT failed\n")) + } + + + if (blocking == true) { + + flutecb->unlock(); + this->waitRx((void *) NULL); + flutecb->lock(); + + } + else if (blocking == false) { + flutecb->unlock(); +#ifdef WIN32 + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) this->waitRx((void *) NULL), (void*)NULL, 0, (LPDWORD)&reception_thread); +#else + pthread_create(&reception_thread, NULL, (void*(*)(void*)) this->waitRx((void *) NULL), (void *)NULL); + pthread_detach(reception_thread); +#endif + flutecb->lock(); + } + + result = this->BytesReceived; + + flutecb->unlock(); + + return result; +} + +/** + * Defines if a file should be overwritten or not: + * possible parameters are: + * PROMPT : prompt before overwriting an existing file, + * NEVER : never overwrite an existing file, + * ALWAYS : always overwrite existing file. + * @param overwrite NEVER, ALWAYS, or PROMPT + */ +void FluteReceiver::setOverwriteFile (int overwrite) { + + flutecb->lock(); + + flutecb->overwrite = overwrite; + + flutecb->unlock(); + +} + + +/** + * Sets the session source address. + * @param src_addr source address + */ +void FluteReceiver::setSrcAddr (struct sockaddr *src_addr) { + + flutecb->lock(); + + flutecb->src_addr = src_addr; + + flutecb->unlock(); + +} + +/** + * Sets the session source address. + * @param source_addr_str source address + */ +void FluteReceiver::setSrcAddr (char *source_addr_str) { + + flutecb->lock(); + + if (flutecb->tools->extract_addr(source_addr_str, &flutecb->src_addr, 0) < 0) { + EXIT(("Flute: setSrcAddr: ERROR, extract_addr failed\n" )) + } + + flutecb->unlock(); + +} + + +/** + * Set the reception directory (where files are written). + * @param recv_dir name of the reception dir + */ +void FluteReceiver::setRecvDir (char * recv_dir) { + + flutecb->lock(); + + flutecb->unlock(); + +} + + +/** + * Set/unset receiving all files. + * @param on_off true: recv all files, + * false: do not recv all files + * ((un)select them individually with + * (un)selectTOI then). + */ +void FluteReceiver::setSelectAll (bool on_off) { + + flutecb->lock(); + + flutecb->storeAllAdu = on_off; + + flutecb->unlock(); + +} + +/** + * Select a file for reception. + * @param toi toi of the file to receive. + */ +void FluteReceiver::selectTOI (TOI_t toi) { + + flutecb->lock(); + + flutecb->fdt->selectTOI(flutecb->myfiles, toi); + + flutecb->unlock(); + +} + +/** + * Unselect a file for reception. + * @param toi toi of the file to not receive. + */ +void FluteReceiver::unselectTOI (TOI_t toi) { + + /*not supported yet*/ + + flutecb->lock(); + flutecb->unlock(); + +} + + +/** + * Flute receiving function (either called as a seperate thread + * (non-blocking) or within the Flute-thread (blocking)). + * @param arg required for threads. + */ +void *FluteReceiver::waitRx(void * arg) { + + char *buf_file = NULL; /* buffer for recv'd fragment */ + UINT64 len = 0; /* available object length */ + /* returned from GET_INFO */ + UINT64 len2 = 0; /* actual object length after */ + /* mcl_recvmsg() call */ + UINT64 fdt_len; /* actual FDT instance length */ + class FluteFile *ThisFile = NULL; + TOI_t toi; + struct mcl_msghdr mh; /* for mcl_recvsmg */ + struct mcl_iovec iov; /* for mcl_recvsmg */ + + /* + * Receive ALL objects... + * Here an object can be either a file or an FDT + */ + memset((void*)&mh, 0, sizeof(mh)); + while ((len = mcl_recvmsg(flutecb->id, &mh, + MCL_MSG_GET_INFO_FOR_AVAILABLE_OBJECT)) != -1) { + + flutecb->lock(); + + toi = (TOI_t) mh.toi; +#ifdef DEBUG + PRINT(("Flute: New Object Received: %llu Bytes, TOI=%u\n", len, toi)) +#endif + if (toi == 0) { + /* + * this is an FDT Instance, so receive the object + * in a buffer + */ + if (!(buf_file = (char*)malloc(len))) { + EXIT(("Flute: Error: Cannot alloc memory!\n")) + } + /* a simple mcl_recv is sufficient here... */ + fdt_len = mcl_recv(flutecb->id, buf_file, len); + if (fdt_len < 0 || fdt_len != len) { + EXIT(("Flute: Error, mcl_recv failed for FDT, fdt_len=%llu\n", fdt_len)) + } + flutecb->fdt->updateFDT(buf_file, len); + + if (flutecb->storeAllAdu == true) + flutecb->fdt->selectAllTOIs(flutecb->myfiles); + /* free this buffer, since next object may be + * significantly shorter or larger */ + free(buf_file); + buf_file = NULL; + + /* call setCallbackReceivedNewFileDescription callback */ + if (this->endOfRx_callback != NULL) { + + class FluteFileInfo* fileinfo; + fileinfo = flutecb->fdt->getFileInfoList(); + flutecb->unlock(); + this->receivedNewFileDescription_callback(fileinfo); + flutecb->lock(); + + } + + + + } else if ((ThisFile = flutecb->myfiles->FFileFindTOI(toi)) != NULL) { + /* + * this is a known and selected file + */ + /* + * Content-Length Check, if this is specified in + * an FDT Instance (i.e. if filesize != 0) + */ + if ((ThisFile->contentLength != 0) && (len != ThisFile->contentLength)) { + EXIT(("Flute: Error, actual length (%lld) different from length specified in FDT (%lld) for TOI %u\n", len, ThisFile->contentLength, toi)) + } + if (ThisFile->writeIt) { + /* + * this file can be written/over-written, so + * prepar the recvmsg call + */ + memset((void*)&mh, 0, sizeof(mh)); + mh.msg_iov = &iov; + mh.msg_iovlen = 1; + iov.iov_type = MCL_IOV_TYPE_FILE; + iov.iov_base = NULL; + iov.iov_filename = ThisFile->fullname; + iov.iov_offset = (INT64)0; + iov.iov_len = (INT64)len; + len2 = mcl_recvmsg(flutecb->id, &mh, MCL_MSG_DEFAULT); + if (len2 != len) { + EXIT(("Flute: Error, mcl_recvmsg failed, returned %lld\n", len)) + } + PRINT(("Flute: Received file \"%s\" (%lld Bytes)\n", + ThisFile->fullname, len)) + ThisFile->received = 1; +#ifndef OPENSSL + this->BytesReceived += len; +#else + /*MD5sum checks*/ + if (strcmp((const char *)ThisFile->md5sum,"\0")==0) { + PRINT(("Flute: No md5sum information for file %s\n", ThisFile->fullname)); + ThisFile->integrity = 0; + this->BytesReceived += len; + } else if (!FFilemd5sum_check(ThisFile)) { + EXIT(("Flute: WARNING: wrong md5sum for file %s\n", ThisFile->fullname)); + //ThisFile->integrity=-1; + } else { + PRINT(("Flute: MD5sum OK, for file %s\n", ThisFile->fullname)) + ThisFile->integrity=1; + this->BytesReceived += len; + } +#endif + } else { + PRINT(("Flute: Skipped file \"%s\"\n", ThisFile->fullname)) + } + } else { + /* + * this is an unknown or unwanted file + */ + PRINT(("Flute: WARNING: Received unknown object TOI %u\n", + toi)) + } + /* reset for next mcl_recvmsg */ + memset((void*)&mh, 0, sizeof(mh)); + + /* Give some time to other function calls */ + flutecb->unlock(); + } + + + if (this->endOfRx_callback != NULL) { + + UINT64 val = this->BytesReceived; + flutecb->unlock(); + this->endOfRx_callback(val); + flutecb->lock(); + + } + + flutecb->unlock(); +} diff --git a/src/flute_lib/FluteReceiver.h b/src/flute_lib/FluteReceiver.h new file mode 100644 index 0000000..6f73f85 --- /dev/null +++ b/src/flute_lib/FluteReceiver.h @@ -0,0 +1,80 @@ +/* $Id: FluteReceiver.h,v 1.3 2005/05/23 11:11:18 roca Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_RECEIVER_H +#define FLUTE_RECEIVER_H +/** + * This Class is the API for flute + */ +class FluteReceiver : public Flute { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + FluteReceiver (); + + /** + * Default destructor. + */ + ~FluteReceiver (); + + /*** get/set functions ***/ + + void setOverwriteFile (INT32 overwrite); + + void setSrcAddr (struct sockaddr *src_addr); + + void setSrcAddr (char *source_addr_str); + + void setRecvDir (char * recv_dir); + + void setSelectAll (bool on_off); + + /*** File info and session control functions ***/ + + UINT64 recv (bool blocking); + + void selectTOI (TOI_t toi) ; + + void unselectTOI (TOI_t toi) ; + + void setCallbackReceivedNewFileDescription (void* + (*ReceivedNewFileDescription_callback) (class FluteFileInfo * fileInfo)); + + void setCallbackEndOfRx ( void* (*EndOfRx_callback)(UINT64 BytesRecvd)); + + +private: + /****** Private Members ***********************************************/ + UINT64 BytesReceived; /* total amount of data recv'd*/ + + void *waitRx(void * arg); + void* (*endOfRx_callback)(UINT64 BytesRecvd); + void* (*receivedNewFileDescription_callback)(class FluteFileInfo * fileInfo); + + flute_thread_t reception_thread; + +}; + +#endif diff --git a/src/flute_lib/FluteSDP.cpp b/src/flute_lib/FluteSDP.cpp new file mode 100644 index 0000000..a6d9c69 --- /dev/null +++ b/src/flute_lib/FluteSDP.cpp @@ -0,0 +1,246 @@ +/* $Id: FluteSDP.cpp,v 1.3 2005/05/24 09:56:16 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * flute_sdp.cpp + * + * Flute sdp parser. + */ + +#include "flute_includes.h" + + + +FluteSDP::FluteSDP (class flute_cb* flutecb) +{ + this->media_part = false; + this->flutecb=flutecb; +} + + + +FluteSDP::~FluteSDP () +{ + this->media_part = false; +} + + + +int flute_sdp_field_handler( + SDP_Parser * parser, + char type, + const char * value, + void * user_data) + { + char * temp; /* temp string for string search operations */ + + switch(type) { + case 'v': + case 'o': + case 'i': + case 't': + break; + case 'a': + if (!strncmp(value, "flute-tsi:", 10) && isdigit((int)*(value+10))) { + ((flute_cb *) user_data)->demux_label = atoi(value+10); + } + else if (!strncmp(value, "flute-ch:", 9) && isdigit((int)*(value+9))){ + ((flute_cb *) user_data)->nb_layers = atoi(value+9); + } + else if (!strncmp(value, "source-filter:", 14) && isdigit((int)*(value+14))){ + if (((flute_cb *) user_data)->sdp->media_part == true) + /* source filters not allowed in media part */ + return SDP_FAILURE; + + if ((temp = strstr(value,"excl")) != NULL) + /* exclusive source filters not allowed */ + return SDP_FAILURE; + + if ((temp = strstr(value,"IN")) == NULL) + /* only IN source filters allowed */ + return SDP_FAILURE; + + + if ((temp = strstr(value,"IP4")) != NULL) + { +#ifdef WIN32 + ((flute_cb *) user_data)->ip_version = 4; +#endif + } + else if ((temp = strstr(value,"IP6")) != NULL) + { +#ifdef WIN32 + ((flute_cb *) user_data)->ip_version = 6; +#endif + + } + + /* get the IP address string */ + temp = strstr(value,"* "); + if (((flute_cb *) user_data)->tools->extract_addr(temp+2, &((flute_cb *) user_data)->src_addr, 0) < 0) { + printf("Flute: ERROR, extract_addr failed for src_addr %s\n", temp+2); + exit(-1); + } + + + if (!isdigit((int)*(temp+1))) + return SDP_FAILURE; + ((flute_cb *) user_data)->port = atoi(temp+1); + + } +#if 0 + else if (!strncmp(value, "FEC-declaration:", 16) && isdigit((int)*(value+16))){ + + } +#endif + break; + case 'm': + /* we are starting parsing the media part */ + if (((flute_cb *) user_data)->sdp->media_part == false) ((flute_cb *) user_data)->sdp->media_part = true; + + /* check if it is a FLUTE media type */ + temp = strstr(value,"FLUTE/UDP"); + if (temp == NULL) + return SDP_FAILURE; + + /* jump to the port number */ + /* (Normally the line looks like: * + * m=application 12345 FLUTE/UDP 0 */ + temp = strstr(value," "); + if (!isdigit((int)*(temp+1))) + return SDP_FAILURE; + ((flute_cb *) user_data)->port = atoi(temp+1); + break; + case 'c': + if ((temp = strstr(value,"IP4")) != NULL) + { +#ifdef WIN32 + ((flute_cb *) user_data)->ip_version = 4; +#endif + } + else if ((temp = strstr(value,"IP6")) != NULL) + { +#ifdef WIN32 + ((flute_cb *) user_data)->ip_version = 6; +#endif + + } + else + return SDP_FAILURE; + + /* get the IP address string */ + { + char *t,*c; + strncpy(((flute_cb *) user_data)->session_addr_str, temp+4, sizeof(((flute_cb *) user_data)->session_addr_str)); + /* ttl */ + if ((t = strchr(((flute_cb *) user_data)->session_addr_str, '/')) != NULL) { + *t = '\0'; + /* number of channels */ + if ((c = strchr(t, '/')) != NULL){ + *c = '\0'; + } + /* in host order */ + ((flute_cb *) user_data)->ttl = (unsigned short)atoi(t+1); + } + ((flute_cb *) user_data)->session_addr_str[255] = '\0'; + } + ((flute_cb *) user_data)->session_address_set = true; + + default: + break; + } + return SDP_SUCCESS; + } + + + +void FluteSDP::parseSDP(char * sdp_filename) +{ + SDP_Parser *sdp_parser; + + sdp_parser = SDP_NewParser(); + + SDP_SetFieldHandler(sdp_parser, (SDP_FieldHandler) &flute_sdp_field_handler); + SDP_SetUserData(sdp_parser, (void *) flutecb); + + if (SDP_EventStreamParseFile(sdp_parser, sdp_filename)!=true) + { + EXIT(("Flute: ERROR, SDP file seems not OK (or some features are not supported by our implementation)\n")) + } + + SDP_DestroyParser(sdp_parser); +} + + + +void FluteSDP::generateSDP(char * sdp_filename) +{ + char temp[256]; + SDP_Generator *generator = SDP_NewGenerator(); + + SDP_GenProtocolVersionField(generator, 0); + + sprintf(temp,"%i",flutecb->demux_label); + SDP_GenAttributeField(generator,"flute-tsi", temp); + memset(temp,0, sizeof(temp)); + + if(flutecb->nb_layers > 0) + { + sprintf(temp,"%i\n",flutecb->nb_layers); + SDP_GenAttributeField(generator,"flute-ch", temp); + memset(temp,0, sizeof(temp)); + } + + sprintf(temp,"%i",flutecb->port); + SDP_GenMediaDescriptionField(generator,"data",temp,"FLUTE/UDP","0"); + memset(temp,0, sizeof(temp)); + + if (flutecb->session_addr != NULL) + { + if (flutecb->session_addr->sa_family == AF_INET) + { + SDP_GenConnectionField(generator,"IN", "IP4", inet_ntoa(((sockaddr_in*) flutecb->session_addr)->sin_addr), flutecb->ttl,1); + } + else if (flutecb->session_addr->sa_family == AF_INET6) + { +#ifdef WIN32 + DWORD len = INET6_ADDRSTRLEN; + if (WSAAddressToString( (LPSOCKADDR) flutecb->session_addr, sizeof(struct sockaddr_in6), NULL, temp, &len)!=0) + { + EXIT(("Flute::flute_generate_sdp: ERROR, WSAStringToAddress failed: %i\n", WSAGetLastError())) + } + +#else /* UNIX */ + inet_ntop(AF_INET6, &(((struct sockaddr_in6*)flutecb->session_addr)->sin6_addr),temp, sizeof(temp)); +#endif + SDP_GenConnectionField(generator,"IN", "IP6", temp, flutecb->ttl,1); + } + } + else + { + SDP_GenConnectionField(generator,"IN", "IP4", "127.0.0.1", flutecb->ttl,1); + } + + SDP_SaveGeneratedOutput(generator,sdp_filename); +} + diff --git a/src/flute_lib/FluteSDP.h b/src/flute_lib/FluteSDP.h new file mode 100644 index 0000000..f9a6217 --- /dev/null +++ b/src/flute_lib/FluteSDP.h @@ -0,0 +1,85 @@ +/* $Id: FluteSDP.h,v 1.2 2005/05/12 16:03:39 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_SDP_H +#define FLUTE_SDP_H + +#include "../sdp_lib/src/SDP_Parser.h" +#include "../sdp_lib/src/SDP_Generator.h" + + +/** + * The field sdp handler (called by the sdp parser + * when it encounters a field while parsing). + * @param parser + * @param type + * @param value + * @param user_data + * @return SDP_FAILURE or SDP_SUCCESS + */ +int flute_sdp_field_handler( + SDP_Parser * parser, + char type, + const char * value, + void * user_data); + + +/** + * This Class handels sdp files for flute + */ +class FluteSDP { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + FluteSDP (class flute_cb * flutecb); + + /** + * Default destructor. + */ + ~FluteSDP (); + + /** + * parses the sdp file and sets the appropriate parameters + */ + void parseSDP(char * sdp_filename); + + + /** + * generates an sdp file + */ + void generateSDP(char * sdp_filename); + + /** are we parsing the media part or not */ + bool media_part; + +private: + + /****** Private Attributes ********************************************/ + class flute_cb * flutecb; + +}; + +#endif diff --git a/src/flute_lib/FluteSender.cpp b/src/flute_lib/FluteSender.cpp new file mode 100644 index 0000000..c7a5568 --- /dev/null +++ b/src/flute_lib/FluteSender.cpp @@ -0,0 +1,90 @@ +/* $Id: FluteSender.cpp,v 1.2 2005/05/12 16:03:40 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "flute_includes.h" + +FluteSender::FluteSender () { + + if ((flutecb->id = mcl_open("w")) < 0) + EXIT(("FluteSender: ERROR, mcl_open(w) failed\n")) + + flutecb->mode = SEND; + flutecb->fec = new FluteFec(flutecb); + carousel = new FluteFileDeliveryCarousel(this); + +} + + +FluteSender::~FluteSender () { + + /* cleanup everything */ + + /* free FEC class if needed */ + if (flutecb->fec != NULL) { + delete flutecb->fec; + flutecb->fec = NULL; + } + + /* free carousel class if needed */ + if (this->carousel != NULL) { + delete this->carousel; + } + +} + + + +bool FluteSender::setFECRatio (float fec_ratio) { + + + flutecb->lock(); + + flutecb->fec_ratio = fec_ratio; + if (mcl_ctl(flutecb->id, MCL_OPT_FEC_RATIO, (void*)&flutecb->fec_ratio, sizeof(flutecb->fec_ratio))) { + flutecb->unlock(); + return false; + } + else { + flutecb->unlock(); + return true; + } +} + + +float FluteSender::getFECRatio () { + + float result; + flutecb->lock(); + result = flutecb->fec_ratio; + flutecb->unlock(); + return result; + +} + +void FluteSender::setTTL (INT32 ttl) { + + flutecb->lock(); + flutecb->ttl = ttl; + flutecb->unlock(); + +} + diff --git a/src/flute_lib/FluteSender.h b/src/flute_lib/FluteSender.h new file mode 100644 index 0000000..2f8e520 --- /dev/null +++ b/src/flute_lib/FluteSender.h @@ -0,0 +1,55 @@ +/* $Id: FluteSender.h,v 1.2 2005/05/12 16:03:40 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_SENDER_H +#define FLUTE_SENDER_H + +class FluteSender : public Flute { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + FluteSender (); + + /** + * Default destructor. + */ + ~FluteSender (); + + + /******* Sender Side **********/ + class FluteFileDeliveryCarousel *carousel; + + bool setFECRatio (float fec_ratio); + + float getFECRatio (); + + void setTTL (INT32 ttl); + +protected: + friend class FluteFileDeliveryCarousel; + +}; + +#endif diff --git a/src/flute_lib/FluteTools.cpp b/src/flute_lib/FluteTools.cpp new file mode 100644 index 0000000..1404d79 --- /dev/null +++ b/src/flute_lib/FluteTools.cpp @@ -0,0 +1,201 @@ +/* $Id: FluteTools.cpp,v 1.3 2005/05/23 11:11:18 roca Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "flute_includes.h" + +FluteTools::FluteTools(class flute_cb *flutecb){ + this->flutecb = flutecb; +} + + +FluteTools::~FluteTools(){ +} + +/** + * Extract an IPv4 or IPv6 address from an address string or host name. + * Copies the address in the sockaddr structure. + * @param addr_string IPv4/IPv6 address string or host name. + * @param addr address of the pointer to sockaddr where to store + * the result. This function allocates the appropriate + * sockaddr_in/sockaddr_in6 structure. + * @param port port number in HOST byte order to store in sockaddr. + * @return 0 if OK, < 0 in case of error. + */ +int FluteTools::extract_addr (char *addr_string, + struct sockaddr **addr, + int port) +{ +// choose one resolver method according to what is available... +#if defined(LINUX) +#define HAS_GETHOSTBYNAME2 // GNU extension, ok on linux +#elif defined(SOLARIS) || defined(FREEBSD) +#define HAS_GETIPNODEBYNAME // POSIX 1003.1-2001 version +#elif defined(WIN32) +#define HAS_NOTHING +#endif + + +#ifdef HAS_GETHOSTBYNAME2 + struct hostent *hp; + + /* search for IPv4/IPv6 hostname or address first */ + hp = gethostbyname2(addr_string, AF_INET); + if (hp != NULL) { + struct sockaddr_in *sa; + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in)); + if (*addr == NULL) { + EXIT(("Flute: ERROR, no memory\n")) + } + sa = (struct sockaddr_in*)*addr; + sa->sin_family = AF_INET; + sa->sin_port = htons(port); + memcpy(&(sa->sin_addr.s_addr), + hp->h_addr_list[0], + sizeof(struct in_addr)); + return 0; + } + hp = gethostbyname2(addr_string, AF_INET6); + if (hp != NULL) { + struct sockaddr_in6 *sa6; + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*) + calloc(1, sizeof(struct sockaddr_in6)); + if (*addr == NULL) { + EXIT(("Flute: ERROR, no memory\n")) + } + sa6 = (struct sockaddr_in6*)*addr; + sa6->sin6_family = AF_INET6; + sa6->sin6_port = htons(port); + memcpy(&(sa6->sin6_addr), hp->h_addr_list[0], + sizeof(struct in6_addr)); + return 0; + } + /* everything failed */ + PRINT(("Flute: ERROR, unknown host ""%s""\n", addr_string)) + return -1; +#endif // HAS_GETHOSTBYNAME2 +#ifdef HAS_GETIPNODEBYNAME + struct hostent *hp; + int err; + + /* search for IPv4 hostname or address first */ + hp = getipnodebyname(addr_string, AF_INET, AI_DEFAULT, &err); + //PRINT(("search for IPv4: returned x%x, err=%d\n", hp, err)) + if (hp != NULL) { + struct sockaddr_in *sa; + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in)); + if (*addr == NULL) { + EXIT(("Flute: ERROR, no memory\n")) + } + sa = (struct sockaddr_in*)*addr; + sa->sin_family = AF_INET; + sa->sin_port = htons(port); + memcpy(&(sa->sin_addr.s_addr), + hp->h_addr_list[0], + sizeof(struct in_addr)); + return 0; + } + /* search for IPv6 hostname or address then */ + hp = getipnodebyname(addr_string, AF_INET6, AI_DEFAULT, &err); + //PRINT(("search for IPv6: returned x%x, err=%d\n", hp, err)) + if (hp != NULL) { + struct sockaddr_in6 *sa6; + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*) + calloc(1, sizeof(struct sockaddr_in6)); + if (*addr == NULL) { + EXIT(("Flute: ERROR, no memory\n")) + } + sa6 = (struct sockaddr_in6*)*addr; + sa6->sin6_family = AF_INET6; + sa6->sin6_port = htons(port); + memcpy(&(sa6->sin6_addr), hp->h_addr_list[0], + sizeof(struct in6_addr)); + return 0; + } + /* everything failed */ + PRINT(("Flute: ERROR, unknown host ""%s""\n", addr_string)) + return -1; +#endif // HAS_GETIPNODEBYNAME +#ifdef HAS_NOTHING + + if (flutecb->ip_version == 4) + { + struct sockaddr_in *sa; + + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*)calloc(1, sizeof(struct sockaddr_in)); + if (*addr == NULL) { + EXIT(("Flute: ERROR, no memory\n")) + } + sa = (struct sockaddr_in*)*addr; + sa->sin_family = AF_INET; + sa->sin_port = htons(port); + /* + * addr must be in host byte order, but + * gethostbyname/inet_addr return network order + */ + if (isalpha((int)addr_string[0])) { + if (gethostbyname(addr_string) == NULL) { + PRINT(("Flute: ERROR, unknown host ""%s""\n", addr_string)) + PRINT(("Flute: did you specify the right IP version?\n")) + free(*addr); + *addr = NULL; + return -1; + } + sa->sin_addr.s_addr = *(unsigned long *)((gethostbyname(addr_string))->h_addr); + } else { + sa->sin_addr.s_addr = inet_addr(addr_string); + } + } + else if (flutecb->ip_version == 6) + { + struct sockaddr_in6 *sa6; + int len = sizeof(struct sockaddr_in6); + /* addr must be in host byte order, but + * hostent is in network order! */ + *addr = (struct sockaddr*) + calloc(1, sizeof(struct sockaddr_in6)); + if (*addr == NULL) { + EXIT(("Flute: ERROR, no memory\n")) + } + sa6 = (struct sockaddr_in6*)*addr; + sa6->sin6_family = AF_INET6; + if (WSAStringToAddress(addr_string, AF_INET6, NULL, (struct sockaddr*) sa6, &len) != 0) + { + EXIT(("Flute: ERROR, WSAStringToAddress failed: %i\n", WSAGetLastError())) + } + sa6->sin6_port = htons(port); + } + + return 0; +#endif // HAS_NOTHING +} + + diff --git a/src/flute_lib/FluteTools.h b/src/flute_lib/FluteTools.h new file mode 100644 index 0000000..4e9235b --- /dev/null +++ b/src/flute_lib/FluteTools.h @@ -0,0 +1,55 @@ +/* $Id: FluteTools.h,v 1.2 2005/05/12 16:03:41 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_TOOLS_H +#define FLUTE_TOOLS_H + + +class FluteTools { + +public: + + FluteTools::FluteTools(class flute_cb * flutecb); + + FluteTools::~FluteTools(); + + /** + * Extract an IPv4 or IPv6 address from an address string or host name. + * Copies the address in the sockaddr structure. + * @param addr_string IPv4/IPv6 address string or host name. + * @param addr address of the pointer to sockaddr where to store + * the result. This function allocates the appropriate + * sockaddr_in/sockaddr_in6 structure. + * @param port port number in HOST byte order to store in sockaddr. + * @return 0 if OK, < 0 in case of error. + */ + int extract_addr (char *addr_string, + struct sockaddr **addr, + int port); + + +private: + + class flute_cb* flutecb; +}; + +#endif diff --git a/src/flute_lib/Makefile b/src/flute_lib/Makefile new file mode 100644 index 0000000..55859ab --- /dev/null +++ b/src/flute_lib/Makefile @@ -0,0 +1,1292 @@ +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../../Makefile.common + + +# libraries required +ifeq (${OS},linux) + # Linux version + # + BINDIR = ../../bin/linux + LDPC_BINDIR = ../../../ldpc/bin/linux + XERCES_DIR = ../../../xerces-c + # Shared version (default) + LIBRARIES = -lc -lm -lpthread + #-lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},solaris) + # Solaris version: + # Warning: SUN recommends to have -lucb at the end of list, + # in order to priviledge SUN's libs to the BSD compatibility + # lib (libucb). + # CC requires: -mt -lpthread for multithreaded applications + # OpenSSL is installed at /usr/local/ssl in our system. Update if + # needed. + # + BINDIR = ../../bin/solaris + LDPC_BINDIR = ../../../ldpc/bin/solaris + XERCES_DIR = ../../../xerces-c + OPENSSL_DIR = /usr/local/ssl + LIBRARIES = -lc -lm -lsocket -lnsl -lposix4 -mt -lpthread -L/usr/ucblib -lucb -L${OPENSSL_DIR}/lib -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include -I${OPENSSL_DIR}/include +endif + +ifeq (${OS},freebsd) + # FreeBSD version: + # CC requires: -mt -lpthread for multithreaded applications + # + BINDIR = ../../bin/freebsd + LDPC_BINDIR = ../../../ldpc/bin/freebsd + XERCES_DIR = ../../../xerces-c + LIBRARIES = -lm -pthread -L/usr/local/lib -lcrypto + #ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include + ADD_INCLUDES = -I${XERCES_DIR}/include +endif + +ifeq (${OS},aix) + # AIX version + BINDIR = ../../bin/aix + LDPC_BINDIR = ../../../ldpc/bin/aix + XERCES_DIR = ../../../xerces-c + LIBRARIES = -lm -pthread -lc -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},hp-ux) + # HP-UX version + BINDIR = ../../bin/hp-ux + LDPC_BINDIR = ../../../ldpc/bin/hp-ux + XERCES_DIR = ../../../xerces-c + LIBRARIES = -lc -lm -pthread -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + +ifeq (${OS},irix) + # IRIX version + BINDIR = ../../bin/irix + LDPC_BINDIR = ../../../ldpc/bin/irix + XERCES_DIR = ../../../xerces-c + LIBRARIES = -lc -lm -pthread -lcrypto + ADD_INCLUDES = -I/usr/local/include/ -I${XERCES_DIR}/include +endif + + +###### Other variables ###### + +# Local CFLAGS. + +# gcc version +#CFLAGS = -g -pg -O ${OSFLAGS} -DALC ${ADD_INCLUDES} +CFLAGS = -g -O -DDEBUG ${OSFLAGS} -DALC ${ADD_INCLUDES} +#CFLAGS = -O ${OSFLAGS} -DALC ${ADD_INCLUDES} +#static: CFLAGS = ${CFLAGS} -static -static-libgcc + +# add purify linker for memory debug (Solaris only). +# Purify 4.0 Solaris 2, Copyright (C) 1992-1996 Pure Software Inc. +# +#CCLINK_PURE = purify $(CC) +CCLINK_PURE = purify -cache-dir=/tmp $(CC) + +# add quantify linker for profiling (Solaris only). +CCLINK_QUANTIFY = quantify $(CC) + +# list of source and object files +SRCFILES = Flute.cpp FluteReceiver.cpp FluteSender.cpp FluteFileInfo.cpp FluteFileDeliveryCarousel.cpp FluteFile.cpp FluteFileList.cpp FluteFec.cpp flute_cb.cpp FluteFDT.cpp flute_md5.cpp flute_lock.cpp FluteSDP.cpp FluteTools.cpp +OFILES = ${SRCFILES:.cpp=.o} + +#OS flag with upper case chars +OS_UPPER_CASE = `echo ${OS} | tr 'a-z' 'A-Z'` + +# XML parsing library +static: XERCES_LIBRARY := ${XERCES_DIR}/lib/libxerces-c.a + +###### Dependancies ###### + +# by default, build the dynamic FLUTE version... +all: lib + +static: xerces_lib all + + +# Rule for C++ .cpp extension +.cpp.o: + $(CC) -c $(CFLAGS) -o $*.o $*.cpp + +lib : ${OFILES} ${MCL_LIBRARY} ${SDP_LIBRARY} + @echo "** Now create the FLUTE library..." + # + # add the libldpc.a the xerces and the sdp library + ${AR} -rcsv ${BINDIR}/libflute.a ${OFILES} + ${RANLIB} ${BINDIR}/libflute.a + @echo "done" + + +xerces_lib : ${XERCES_LIBRARY} + @echo "** Now create the Xerces library..." + @for f in ${XERCES_DIR}/lib/libxerces-c.a; do \ + if [ -f "$${f}" ] ; then \ + echo "libxerces-c.a already exists (I will remove it and rebuilt it)"; \ + rm $${f} ; \ + ${AR} -rcsv ${XERCES_DIR}/lib/libxerces-c.a ${XERCES_DIR}/obj/${OS_UPPER_CASE}/*.o; \ + ${RANLIB} ${XERCES_DIR}/lib/libxerces-c.a; \ + else \ + ${AR} -rcsv ${XERCES_DIR}/lib/libxerces-c.a ${XERCES_DIR}/obj/${OS_UPPER_CASE}/*.o; \ + ${RANLIB} ${XERCES_DIR}/lib/libxerces-c.a; \ + fi \ + done + + +clean : + @for f in core ${OFILES} *_pure* *.pure_* .pur* *purify* ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in ${BINDIR}/flute ${BINDIR}/flute-static; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend : + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +Flute.o: flute_includes.h /usr/local/include/xercesc/util/PlatformUtils.hpp +Flute.o: /usr/local/include/xercesc/util/XMLException.hpp +Flute.o: /usr/local/include/xercesc/util/XMemory.hpp +Flute.o: /usr/local/include/xercesc/util/XercesDefs.hpp +Flute.o: /usr/local/include/xercesc/util/XercesVersion.hpp +Flute.o: /usr/local/include/xercesc/util/AutoSense.hpp +Flute.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMError.hpp +Flute.o: /usr/local/include/xercesc/util/XMLUni.hpp +Flute.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +Flute.o: /usr/local/include/xercesc/util/PanicHandler.hpp +Flute.o: /usr/local/include/xercesc/dom/DOM.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMNode.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMText.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMComment.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMElement.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMException.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMRange.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +Flute.o: /usr/local/include/xercesc/util/XMLString.hpp +Flute.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +Flute.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +Flute.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +Flute.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +Flute.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +Flute.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +Flute.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +Flute.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +Flute.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +Flute.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +Flute.o: /usr/local/include/xercesc/sax/InputSource.hpp +Flute.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +Flute.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +Flute.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +Flute.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h FluteTools.h +Flute.o: flute_lock.h FluteFDT.h FluteSDP.h ../sdp_lib/src/SDP_Parser.h +Flute.o: ../sdp_lib/src/SDP_Error.h ../sdp_lib/src/SDP_EventStreamParser.h +Flute.o: ../sdp_lib/src/SDP_StreamTokenizer.h ../sdp_lib/src/SDP_Utility.h +Flute.o: ../sdp_lib/src/SDP_Description.h ../sdp_lib/src/SDP_Str.h +Flute.o: ../sdp_lib/src/SDP_LinkedList.h ../sdp_lib/src/SDP_Generator.h +Flute.o: ../sdp_lib/src/SDP_Generator.h flute_md5.h flute_cb.h FluteFec.h +Flute.o: FluteFile.h FluteFileList.h +FluteReceiver.o: flute_includes.h +FluteReceiver.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteReceiver.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteReceiver.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteReceiver.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteReceiver.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteReceiver.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteReceiver.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteReceiver.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteReceiver.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteReceiver.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteReceiver.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteReceiver.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +FluteReceiver.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h +FluteReceiver.o: FluteSender.h FluteFileInfo.h FluteFileDeliveryCarousel.h +FluteReceiver.o: macros.h FluteTools.h flute_lock.h FluteFDT.h FluteSDP.h +FluteReceiver.o: ../sdp_lib/src/SDP_Parser.h ../sdp_lib/src/SDP_Error.h +FluteReceiver.o: ../sdp_lib/src/SDP_EventStreamParser.h +FluteReceiver.o: ../sdp_lib/src/SDP_StreamTokenizer.h +FluteReceiver.o: ../sdp_lib/src/SDP_Utility.h +FluteReceiver.o: ../sdp_lib/src/SDP_Description.h ../sdp_lib/src/SDP_Str.h +FluteReceiver.o: ../sdp_lib/src/SDP_LinkedList.h +FluteReceiver.o: ../sdp_lib/src/SDP_Generator.h +FluteReceiver.o: ../sdp_lib/src/SDP_Generator.h flute_md5.h flute_cb.h +FluteReceiver.o: FluteFec.h FluteFile.h FluteFileList.h +FluteSender.o: flute_includes.h +FluteSender.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteSender.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteSender.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteSender.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteSender.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteSender.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteSender.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteSender.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteSender.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteSender.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteSender.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteSender.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteSender.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteSender.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteSender.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteSender.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteSender.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteSender.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteSender.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteSender.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteSender.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteSender.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteSender.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteSender.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +FluteSender.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +FluteSender.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h +FluteSender.o: FluteTools.h flute_lock.h FluteFDT.h FluteSDP.h +FluteSender.o: ../sdp_lib/src/SDP_Parser.h ../sdp_lib/src/SDP_Error.h +FluteSender.o: ../sdp_lib/src/SDP_EventStreamParser.h +FluteSender.o: ../sdp_lib/src/SDP_StreamTokenizer.h +FluteSender.o: ../sdp_lib/src/SDP_Utility.h ../sdp_lib/src/SDP_Description.h +FluteSender.o: ../sdp_lib/src/SDP_Str.h ../sdp_lib/src/SDP_LinkedList.h +FluteSender.o: ../sdp_lib/src/SDP_Generator.h ../sdp_lib/src/SDP_Generator.h +FluteSender.o: flute_md5.h flute_cb.h FluteFec.h FluteFile.h FluteFileList.h +FluteFileInfo.o: flute_includes.h +FluteFileInfo.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteFileInfo.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteFileInfo.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteFileInfo.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteFileInfo.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteFileInfo.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteFileInfo.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteFileInfo.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteFileInfo.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteFileInfo.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteFileInfo.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteFileInfo.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +FluteFileInfo.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h +FluteFileInfo.o: FluteSender.h FluteFileInfo.h FluteFileDeliveryCarousel.h +FluteFileInfo.o: macros.h FluteTools.h flute_lock.h FluteFDT.h FluteSDP.h +FluteFileInfo.o: ../sdp_lib/src/SDP_Parser.h ../sdp_lib/src/SDP_Error.h +FluteFileInfo.o: ../sdp_lib/src/SDP_EventStreamParser.h +FluteFileInfo.o: ../sdp_lib/src/SDP_StreamTokenizer.h +FluteFileInfo.o: ../sdp_lib/src/SDP_Utility.h +FluteFileInfo.o: ../sdp_lib/src/SDP_Description.h ../sdp_lib/src/SDP_Str.h +FluteFileInfo.o: ../sdp_lib/src/SDP_LinkedList.h +FluteFileInfo.o: ../sdp_lib/src/SDP_Generator.h +FluteFileInfo.o: ../sdp_lib/src/SDP_Generator.h flute_md5.h flute_cb.h +FluteFileInfo.o: FluteFec.h FluteFile.h FluteFileList.h +FluteFileDeliveryCarousel.o: flute_includes.h +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteFileDeliveryCarousel.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteFileDeliveryCarousel.o: FluteAPI.h ../common/mcl_lib_api.h +FluteFileDeliveryCarousel.o: ../common/mcl_types.h ../alc/mcl_lib_api_alc.h +FluteFileDeliveryCarousel.o: Flute.h FluteReceiver.h FluteSender.h +FluteFileDeliveryCarousel.o: FluteFileInfo.h FluteFileDeliveryCarousel.h +FluteFileDeliveryCarousel.o: macros.h FluteTools.h flute_lock.h FluteFDT.h +FluteFileDeliveryCarousel.o: FluteSDP.h ../sdp_lib/src/SDP_Parser.h +FluteFileDeliveryCarousel.o: ../sdp_lib/src/SDP_Error.h +FluteFileDeliveryCarousel.o: ../sdp_lib/src/SDP_EventStreamParser.h +FluteFileDeliveryCarousel.o: ../sdp_lib/src/SDP_StreamTokenizer.h +FluteFileDeliveryCarousel.o: ../sdp_lib/src/SDP_Utility.h +FluteFileDeliveryCarousel.o: ../sdp_lib/src/SDP_Description.h +FluteFileDeliveryCarousel.o: ../sdp_lib/src/SDP_Str.h +FluteFileDeliveryCarousel.o: ../sdp_lib/src/SDP_LinkedList.h +FluteFileDeliveryCarousel.o: ../sdp_lib/src/SDP_Generator.h +FluteFileDeliveryCarousel.o: ../sdp_lib/src/SDP_Generator.h flute_md5.h +FluteFileDeliveryCarousel.o: flute_cb.h FluteFec.h FluteFile.h +FluteFileDeliveryCarousel.o: FluteFileList.h +FluteFile.o: flute_includes.h +FluteFile.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteFile.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteFile.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteFile.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteFile.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteFile.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteFile.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteFile.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteFile.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteFile.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteFile.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteFile.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteFile.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteFile.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteFile.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteFile.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteFile.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteFile.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteFile.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteFile.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteFile.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteFile.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteFile.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteFile.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +FluteFile.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +FluteFile.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h +FluteFile.o: FluteTools.h flute_lock.h FluteFDT.h FluteSDP.h +FluteFile.o: ../sdp_lib/src/SDP_Parser.h ../sdp_lib/src/SDP_Error.h +FluteFile.o: ../sdp_lib/src/SDP_EventStreamParser.h +FluteFile.o: ../sdp_lib/src/SDP_StreamTokenizer.h +FluteFile.o: ../sdp_lib/src/SDP_Utility.h ../sdp_lib/src/SDP_Description.h +FluteFile.o: ../sdp_lib/src/SDP_Str.h ../sdp_lib/src/SDP_LinkedList.h +FluteFile.o: ../sdp_lib/src/SDP_Generator.h ../sdp_lib/src/SDP_Generator.h +FluteFile.o: flute_md5.h flute_cb.h FluteFec.h FluteFile.h FluteFileList.h +FluteFileList.o: flute_includes.h +FluteFileList.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteFileList.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteFileList.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteFileList.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteFileList.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteFileList.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteFileList.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteFileList.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteFileList.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteFileList.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteFileList.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteFileList.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteFileList.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteFileList.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteFileList.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteFileList.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteFileList.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteFileList.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteFileList.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteFileList.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteFileList.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteFileList.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteFileList.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteFileList.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +FluteFileList.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h +FluteFileList.o: FluteSender.h FluteFileInfo.h FluteFileDeliveryCarousel.h +FluteFileList.o: macros.h FluteTools.h flute_lock.h FluteFDT.h FluteSDP.h +FluteFileList.o: ../sdp_lib/src/SDP_Parser.h ../sdp_lib/src/SDP_Error.h +FluteFileList.o: ../sdp_lib/src/SDP_EventStreamParser.h +FluteFileList.o: ../sdp_lib/src/SDP_StreamTokenizer.h +FluteFileList.o: ../sdp_lib/src/SDP_Utility.h +FluteFileList.o: ../sdp_lib/src/SDP_Description.h ../sdp_lib/src/SDP_Str.h +FluteFileList.o: ../sdp_lib/src/SDP_LinkedList.h +FluteFileList.o: ../sdp_lib/src/SDP_Generator.h +FluteFileList.o: ../sdp_lib/src/SDP_Generator.h flute_md5.h flute_cb.h +FluteFileList.o: FluteFec.h FluteFile.h FluteFileList.h +FluteFec.o: flute_includes.h +FluteFec.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteFec.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteFec.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteFec.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteFec.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteFec.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteFec.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteFec.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteFec.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteFec.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteFec.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteFec.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteFec.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteFec.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteFec.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteFec.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteFec.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteFec.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteFec.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteFec.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteFec.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteFec.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteFec.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteFec.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +FluteFec.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +FluteFec.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h FluteTools.h +FluteFec.o: flute_lock.h FluteFDT.h FluteSDP.h ../sdp_lib/src/SDP_Parser.h +FluteFec.o: ../sdp_lib/src/SDP_Error.h ../sdp_lib/src/SDP_EventStreamParser.h +FluteFec.o: ../sdp_lib/src/SDP_StreamTokenizer.h ../sdp_lib/src/SDP_Utility.h +FluteFec.o: ../sdp_lib/src/SDP_Description.h ../sdp_lib/src/SDP_Str.h +FluteFec.o: ../sdp_lib/src/SDP_LinkedList.h ../sdp_lib/src/SDP_Generator.h +FluteFec.o: ../sdp_lib/src/SDP_Generator.h flute_md5.h flute_cb.h FluteFec.h +FluteFec.o: FluteFile.h FluteFileList.h +flute_cb.o: flute_includes.h +flute_cb.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +flute_cb.o: /usr/local/include/xercesc/util/XMLException.hpp +flute_cb.o: /usr/local/include/xercesc/util/XMemory.hpp +flute_cb.o: /usr/local/include/xercesc/util/XercesDefs.hpp +flute_cb.o: /usr/local/include/xercesc/util/XercesVersion.hpp +flute_cb.o: /usr/local/include/xercesc/util/AutoSense.hpp +flute_cb.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMError.hpp +flute_cb.o: /usr/local/include/xercesc/util/XMLUni.hpp +flute_cb.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +flute_cb.o: /usr/local/include/xercesc/util/PanicHandler.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOM.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMNode.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMText.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMComment.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMElement.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMException.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMRange.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +flute_cb.o: /usr/local/include/xercesc/util/XMLString.hpp +flute_cb.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +flute_cb.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +flute_cb.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +flute_cb.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +flute_cb.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +flute_cb.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +flute_cb.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +flute_cb.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +flute_cb.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +flute_cb.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +flute_cb.o: /usr/local/include/xercesc/sax/InputSource.hpp +flute_cb.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +flute_cb.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +flute_cb.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +flute_cb.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h FluteTools.h +flute_cb.o: flute_lock.h FluteFDT.h FluteSDP.h ../sdp_lib/src/SDP_Parser.h +flute_cb.o: ../sdp_lib/src/SDP_Error.h ../sdp_lib/src/SDP_EventStreamParser.h +flute_cb.o: ../sdp_lib/src/SDP_StreamTokenizer.h ../sdp_lib/src/SDP_Utility.h +flute_cb.o: ../sdp_lib/src/SDP_Description.h ../sdp_lib/src/SDP_Str.h +flute_cb.o: ../sdp_lib/src/SDP_LinkedList.h ../sdp_lib/src/SDP_Generator.h +flute_cb.o: ../sdp_lib/src/SDP_Generator.h flute_md5.h flute_cb.h FluteFec.h +flute_cb.o: FluteFile.h FluteFileList.h +FluteFDT.o: flute_includes.h +FluteFDT.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteFDT.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteFDT.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteFDT.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteFDT.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteFDT.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteFDT.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteFDT.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteFDT.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteFDT.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteFDT.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteFDT.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteFDT.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteFDT.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteFDT.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteFDT.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteFDT.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteFDT.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteFDT.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteFDT.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteFDT.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteFDT.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteFDT.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteFDT.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +FluteFDT.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +FluteFDT.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h FluteTools.h +FluteFDT.o: flute_lock.h FluteFDT.h FluteSDP.h ../sdp_lib/src/SDP_Parser.h +FluteFDT.o: ../sdp_lib/src/SDP_Error.h ../sdp_lib/src/SDP_EventStreamParser.h +FluteFDT.o: ../sdp_lib/src/SDP_StreamTokenizer.h ../sdp_lib/src/SDP_Utility.h +FluteFDT.o: ../sdp_lib/src/SDP_Description.h ../sdp_lib/src/SDP_Str.h +FluteFDT.o: ../sdp_lib/src/SDP_LinkedList.h ../sdp_lib/src/SDP_Generator.h +FluteFDT.o: ../sdp_lib/src/SDP_Generator.h flute_md5.h flute_cb.h FluteFec.h +FluteFDT.o: FluteFile.h FluteFileList.h +flute_md5.o: flute_includes.h +flute_md5.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +flute_md5.o: /usr/local/include/xercesc/util/XMLException.hpp +flute_md5.o: /usr/local/include/xercesc/util/XMemory.hpp +flute_md5.o: /usr/local/include/xercesc/util/XercesDefs.hpp +flute_md5.o: /usr/local/include/xercesc/util/XercesVersion.hpp +flute_md5.o: /usr/local/include/xercesc/util/AutoSense.hpp +flute_md5.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMError.hpp +flute_md5.o: /usr/local/include/xercesc/util/XMLUni.hpp +flute_md5.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +flute_md5.o: /usr/local/include/xercesc/util/PanicHandler.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOM.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMNode.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMText.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMComment.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMElement.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMException.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMRange.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +flute_md5.o: /usr/local/include/xercesc/util/XMLString.hpp +flute_md5.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +flute_md5.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +flute_md5.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +flute_md5.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +flute_md5.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +flute_md5.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +flute_md5.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +flute_md5.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +flute_md5.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +flute_md5.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +flute_md5.o: /usr/local/include/xercesc/sax/InputSource.hpp +flute_md5.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +flute_md5.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +flute_md5.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +flute_md5.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h +flute_md5.o: FluteTools.h flute_lock.h FluteFDT.h FluteSDP.h +flute_md5.o: ../sdp_lib/src/SDP_Parser.h ../sdp_lib/src/SDP_Error.h +flute_md5.o: ../sdp_lib/src/SDP_EventStreamParser.h +flute_md5.o: ../sdp_lib/src/SDP_StreamTokenizer.h +flute_md5.o: ../sdp_lib/src/SDP_Utility.h ../sdp_lib/src/SDP_Description.h +flute_md5.o: ../sdp_lib/src/SDP_Str.h ../sdp_lib/src/SDP_LinkedList.h +flute_md5.o: ../sdp_lib/src/SDP_Generator.h ../sdp_lib/src/SDP_Generator.h +flute_md5.o: flute_md5.h flute_cb.h FluteFec.h FluteFile.h FluteFileList.h +flute_lock.o: flute_includes.h +flute_lock.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +flute_lock.o: /usr/local/include/xercesc/util/XMLException.hpp +flute_lock.o: /usr/local/include/xercesc/util/XMemory.hpp +flute_lock.o: /usr/local/include/xercesc/util/XercesDefs.hpp +flute_lock.o: /usr/local/include/xercesc/util/XercesVersion.hpp +flute_lock.o: /usr/local/include/xercesc/util/AutoSense.hpp +flute_lock.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMError.hpp +flute_lock.o: /usr/local/include/xercesc/util/XMLUni.hpp +flute_lock.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +flute_lock.o: /usr/local/include/xercesc/util/PanicHandler.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOM.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMNode.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMText.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMComment.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMElement.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMException.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMRange.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +flute_lock.o: /usr/local/include/xercesc/util/XMLString.hpp +flute_lock.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +flute_lock.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +flute_lock.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +flute_lock.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +flute_lock.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +flute_lock.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +flute_lock.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +flute_lock.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +flute_lock.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +flute_lock.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +flute_lock.o: /usr/local/include/xercesc/sax/InputSource.hpp +flute_lock.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +flute_lock.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +flute_lock.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +flute_lock.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h +flute_lock.o: FluteTools.h flute_lock.h FluteFDT.h FluteSDP.h +flute_lock.o: ../sdp_lib/src/SDP_Parser.h ../sdp_lib/src/SDP_Error.h +flute_lock.o: ../sdp_lib/src/SDP_EventStreamParser.h +flute_lock.o: ../sdp_lib/src/SDP_StreamTokenizer.h +flute_lock.o: ../sdp_lib/src/SDP_Utility.h ../sdp_lib/src/SDP_Description.h +flute_lock.o: ../sdp_lib/src/SDP_Str.h ../sdp_lib/src/SDP_LinkedList.h +flute_lock.o: ../sdp_lib/src/SDP_Generator.h ../sdp_lib/src/SDP_Generator.h +flute_lock.o: flute_md5.h flute_cb.h FluteFec.h FluteFile.h FluteFileList.h +FluteSDP.o: flute_includes.h +FluteSDP.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteSDP.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteSDP.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteSDP.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteSDP.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteSDP.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteSDP.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteSDP.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteSDP.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteSDP.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteSDP.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteSDP.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteSDP.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteSDP.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteSDP.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteSDP.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteSDP.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteSDP.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteSDP.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteSDP.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteSDP.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteSDP.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteSDP.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteSDP.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +FluteSDP.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +FluteSDP.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h FluteTools.h +FluteSDP.o: flute_lock.h FluteFDT.h FluteSDP.h ../sdp_lib/src/SDP_Parser.h +FluteSDP.o: ../sdp_lib/src/SDP_Error.h ../sdp_lib/src/SDP_EventStreamParser.h +FluteSDP.o: ../sdp_lib/src/SDP_StreamTokenizer.h ../sdp_lib/src/SDP_Utility.h +FluteSDP.o: ../sdp_lib/src/SDP_Description.h ../sdp_lib/src/SDP_Str.h +FluteSDP.o: ../sdp_lib/src/SDP_LinkedList.h ../sdp_lib/src/SDP_Generator.h +FluteSDP.o: ../sdp_lib/src/SDP_Generator.h flute_md5.h flute_cb.h FluteFec.h +FluteSDP.o: FluteFile.h FluteFileList.h +FluteTools.o: flute_includes.h +FluteTools.o: /usr/local/include/xercesc/util/PlatformUtils.hpp +FluteTools.o: /usr/local/include/xercesc/util/XMLException.hpp +FluteTools.o: /usr/local/include/xercesc/util/XMemory.hpp +FluteTools.o: /usr/local/include/xercesc/util/XercesDefs.hpp +FluteTools.o: /usr/local/include/xercesc/util/XercesVersion.hpp +FluteTools.o: /usr/local/include/xercesc/util/AutoSense.hpp +FluteTools.o: /usr/local/include/xercesc/util/XMLExceptMsgs.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMError.hpp +FluteTools.o: /usr/local/include/xercesc/util/XMLUni.hpp +FluteTools.o: /usr/local/include/xercesc/framework/XMLErrorReporter.hpp +FluteTools.o: /usr/local/include/xercesc/util/PanicHandler.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOM.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMAttr.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMNode.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMCDATASection.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMText.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMCharacterData.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMComment.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMDocument.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMDocumentRange.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMDocumentTraversal.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMXPathEvaluator.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMDocumentFragment.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMDocumentType.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMElement.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMEntity.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMEntityReference.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMException.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMImplementation.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMImplementationLS.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMRangeException.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMNamedNodeMap.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMNodeList.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMNotation.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMProcessingInstruction.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMNodeFilter.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMNodeIterator.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMRange.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMTreeWalker.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMBuilder.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMConfiguration.hpp +FluteTools.o: /usr/local/include/xercesc/util/XMLString.hpp +FluteTools.o: /usr/local/include/xercesc/util/BaseRefVectorOf.hpp +FluteTools.o: /usr/local/include/xercesc/util/ArrayIndexOutOfBoundsException.hpp +FluteTools.o: /usr/local/include/xercesc/util/XMLEnumerator.hpp +FluteTools.o: /usr/local/include/xercesc/framework/MemoryManager.hpp +FluteTools.o: /usr/local/include/xercesc/util/BaseRefVectorOf.c +FluteTools.o: /usr/local/include/xercesc/framework/XMLBuffer.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMEntityResolver.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMErrorHandler.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMImplementationRegistry.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMImplementationSource.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMInputSource.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMLocator.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMTypeInfo.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMUserDataHandler.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMWriter.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMWriterFilter.hpp +FluteTools.o: /usr/local/include/xercesc/framework/XMLFormatter.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMXPathNSResolver.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMXPathException.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMXPathExpression.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMXPathResult.hpp +FluteTools.o: /usr/local/include/xercesc/dom/DOMXPathNamespace.hpp +FluteTools.o: /usr/local/include/xercesc/framework/Wrapper4InputSource.hpp +FluteTools.o: /usr/local/include/xercesc/framework/MemBufInputSource.hpp +FluteTools.o: /usr/local/include/xercesc/sax/InputSource.hpp +FluteTools.o: /usr/local/include/xercesc/framework/MemBufFormatTarget.hpp +FluteTools.o: FluteAPI.h ../common/mcl_lib_api.h ../common/mcl_types.h +FluteTools.o: ../alc/mcl_lib_api_alc.h Flute.h FluteReceiver.h FluteSender.h +FluteTools.o: FluteFileInfo.h FluteFileDeliveryCarousel.h macros.h +FluteTools.o: FluteTools.h flute_lock.h FluteFDT.h FluteSDP.h +FluteTools.o: ../sdp_lib/src/SDP_Parser.h ../sdp_lib/src/SDP_Error.h +FluteTools.o: ../sdp_lib/src/SDP_EventStreamParser.h +FluteTools.o: ../sdp_lib/src/SDP_StreamTokenizer.h +FluteTools.o: ../sdp_lib/src/SDP_Utility.h ../sdp_lib/src/SDP_Description.h +FluteTools.o: ../sdp_lib/src/SDP_Str.h ../sdp_lib/src/SDP_LinkedList.h +FluteTools.o: ../sdp_lib/src/SDP_Generator.h ../sdp_lib/src/SDP_Generator.h +FluteTools.o: flute_md5.h flute_cb.h FluteFec.h FluteFile.h FluteFileList.h diff --git a/src/flute_lib/flute_cb.cpp b/src/flute_lib/flute_cb.cpp new file mode 100644 index 0000000..06d88e9 --- /dev/null +++ b/src/flute_lib/flute_cb.cpp @@ -0,0 +1,137 @@ +/* $Id: flute_cb.cpp,v 1.4 2005/05/23 11:11:18 roca Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "flute_includes.h" + +flute_cb::flute_cb () +{ + + this->id = 0; + this->verbose = 0; + this->stats = 0; + this->mode=NOT_INITIALIZED; + this->session_address_set = false; + this->session_addr = NULL; + this->src_addr = NULL; + this->mcast_if_addr = NULL; + this->mcast_if_name = NULL; + this->port = 9998; + this->demux_label = 0; + this->ssm = false; + this->ttl = 1; + this->fec_ratio = 2.0; + this->reuse_tx_buff = 1; + +#ifdef WIN32 + this->overwrite = PROMPT; +#else + this->overwrite = ALWAYS; +#endif + + this->storeAllAdu = true; // by default + +#ifdef WIN32 + this->pause = false; + this->ip_version = 4; +#endif + this->tx_huge_file = 0; + this->tmp_dir_set = 0; + this->txprof_set = false; /* set tx profile only once */ + this->txprof_mode = MCL_TX_PROFILE_MID_RATE_INTERNET; + this->txprof_dt_size = 0; /* default datagram size in bytes */ + this->txprof_rate = 0.0; /* default rate in pkts/s (converted + from bps)*/ + this->congestion_control = FLID_SL_CC; + + this->nb_layers = 0; + this->nb_tx = 0; + this->delivery_mode = DEL_MODE_PUSH; + this->myfiles=NULL; + + /* FEC is NULL at startup and only get initizlized if is a sender*/ + this->fec = NULL; + + /* No sdp parser nedded to start with */ + this->sdp = NULL; + + /* Initialize fdt */ + this->fdt = new FluteFDT(this); + + /* Initialize tools */ + this->tools = new FluteTools(this); + + this->myfiles = new FluteFileList(this); + + /* Initialize mutex */ + flute_init_lock(&this->flutemutex); + + this->initialized = false; + this->toiindex = 0; + + this->fdtinstance = NULL; + +} + + +flute_cb::~flute_cb () +{ + + /* cleanup everything */ + + + /* free sdp class if needed */ + if (this->sdp != NULL) { + delete this->sdp; + this->sdp = NULL; + } + + /* free tools class if needed */ + if (this->tools != NULL) { + delete this->tools; + this->tools = NULL; + } + + /* free fdt class */ + if (this->fdt != NULL) { + delete this->fdt; + this->fdt = NULL; + } + + /* free myfiles class */ + if (this->myfiles != NULL) { + delete this->myfiles; + this->myfiles = NULL; + } + + /* free fdt-instance class */ + if (this->fdtinstance != NULL) { + fdtinstance->release(); + this->fdtinstance=NULL; + } + + /* free FEC class if needed */ + if (this->fec != NULL) { + delete this->fec; + this->fec = NULL; + } +} diff --git a/src/flute_lib/flute_cb.h b/src/flute_lib/flute_cb.h new file mode 100644 index 0000000..0431a3b --- /dev/null +++ b/src/flute_lib/flute_cb.h @@ -0,0 +1,165 @@ +/* $Id: flute_cb.h,v 1.5 2005/05/24 09:56:16 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef FLUTE_CB_H +#define FLUTE_CB_H + +#include "flute_includes.h" + + +/** + * This Class handles the main flute parameters + */ +class flute_cb { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + flute_cb (); + + /** + * Default destructor. + */ + ~flute_cb (); + + /** + * + */ + void lock (); + + /** + * + */ + void unlock (); + + /** + * id of the mcl session + */ + INT32 id; + + /** + * has the cb been succesfully intitialized ? + */ + bool initialized; + + /** + * verbosity + */ + INT32 verbose; + + /** + * how detailled display the statistic + */ + INT32 stats; + + /** + * either in SEND or RECV mode (or NOT_INITIALIZED) + */ + INT32 mode; + + /** + * session name string. + */ + char session_addr_str[256]; /* session address string */ + + bool session_address_set; + + struct sockaddr *session_addr; /* IPv4/v6 session address */ + struct sockaddr *src_addr; /* IPv4/v6 sender address */ + struct sockaddr *mcast_if_addr; /* IPv4/v6 interface address */ + char *mcast_if_name; /* interface name (IPv4/IPv6) */ + INT32 port; + INT32 demux_label; + bool ssm; /* tells if SSM mode is set or not */ + + INT32 ttl; + + float fec_ratio; + + bool storeAllAdu; + + INT32 reuse_tx_buff; + + INT32 overwrite; /* PROMPT, ALWAYS, NEVER */ +#ifdef WIN32 + bool pause; + INT32 ip_version; +#endif + INT32 tx_huge_file; + + char tmp_dir[MAX_PATH + MAX_FILENAME]; + INT32 tmp_dir_set; + + /* transmission profile variables */ + bool txprof_set; /* set tx profile only once */ + INT32 txprof_mode; + INT32 txprof_dt_size; /* default datagram size in bytes */ + double txprof_rate; /* default rate in pkts/s (converted from + bps and rounded to upper integer) */ + INT32 congestion_control; + + INT32 nb_layers; + INT32 nb_tx; + INT32 delivery_mode; + + + XERCES_CPP_NAMESPACE_QUALIFIER DOMDocument* fdtinstance; + + /** Classes */ + class FluteSDP *sdp; + class FluteFDT *fdt; + class FluteTools *tools; + + /** Sender Side */ + class FluteFec *fec; + + + /** Receiver Side */ + class FluteFileList *myfiles; + + /* sender side */ + TOI_t toiindex; + + +private: + flute_mutex_t flutemutex; + +}; + + +inline void +flute_cb::lock () +{ + flute_lock(&(this->flutemutex)); +} + +inline void +flute_cb::unlock () +{ + flute_unlock(&(this->flutemutex)); +} + + +#endif diff --git a/src/flute_lib/flute_includes.h b/src/flute_lib/flute_includes.h new file mode 100644 index 0000000..c3e6b6a --- /dev/null +++ b/src/flute_lib/flute_includes.h @@ -0,0 +1,51 @@ +/* $Id: flute_includes.h,v 1.2 2005/05/12 16:03:43 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#include +#include +#include +#include +#include +#if 0 +#include +#endif + +#include "FluteAPI.h" +#include "macros.h" +#include "FluteTools.h" +#include "flute_lock.h" +#include "FluteFDT.h" +#include "FluteSDP.h" +#include "flute_md5.h" +#include "flute_cb.h" +#include "FluteFec.h" +#include "FluteFile.h" +#include "FluteFileList.h" + +/* other constants, do not edit */ +#define NOT_INITIALIZED 0 +#define SEND 1 +#define RECV 2 + +#define READY 0 +#define IN_TX 1 diff --git a/src/flute_lib/flute_lib.vcproj b/src/flute_lib/flute_lib.vcproj new file mode 100755 index 0000000..3caeb6d --- /dev/null +++ b/src/flute_lib/flute_lib.vcproj @@ -0,0 +1,195 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/flute_lib/flute_lock.cpp b/src/flute_lib/flute_lock.cpp new file mode 100644 index 0000000..2f0dbde --- /dev/null +++ b/src/flute_lib/flute_lock.cpp @@ -0,0 +1,112 @@ +/* $Id: flute_lock.cpp,v 1.2 2005/05/12 16:03:43 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * (main author: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * OS dependant code + */ + +#include "flute_includes.h" + + +/** + * initialize a mutex lock + * @param mutex mutex to initialize + */ +void +flute_init_lock (flute_mutex_t *mutex) +{ +#if defined(WIN32) + InitializeCriticalSection(mutex); +#elif defined(NO_PTHREAD_LOCK) + /* Linux pthread lock not working with old ver*/ + *mutex = 0; +#else + { + pthread_mutex_t mutex_init = PTHREAD_MUTEX_INITIALIZER; + memcpy(mutex, &mutex_init, sizeof(pthread_mutex_t)); + } +#endif +} + + + +/** + * get this lock + * @param mutex mutex lock + */ +void +flute_lock (flute_mutex_t *mutex) +{ +#ifdef WIN32 + EnterCriticalSection(mutex); +#elif defined(NO_PTHREAD_LOCK) + /* XXX: horrible synchro but have pbs with pthread_mutex_lock */ + while (*mutex > 0) { + mcl_usleep(100); + } + (*mutex)++; +#else + pthread_mutex_lock(mutex); +#endif /* OS_DEP */ +} + + +/* + * try to get a lock + * @param mclcb + * @return return EBUSY if not possible, 0 if ok + */ +int +flute_trylock (flute_mutex_t *mutex) +{ +#ifdef WIN32 + return 1; /* non 0 to simulate error */ +#elif defined(NO_PTHREAD_LOCK) + /* XXX: horrible synchro but have pbs with pthread_mutex_lock */ + if (*mutex > 0) { + return EBUSY; + } + (*mutex)++; + return 0; +#else + return pthread_mutex_trylock(mutex); +#endif /* OS_DEP */ +} + + + +/** + * release a lock + * @param mutex mutex lock + */ +void +flute_unlock (flute_mutex_t *mutex) +{ +#ifdef WIN32 + LeaveCriticalSection(mutex); +#elif defined(NO_PTHREAD_LOCK) + (*mutex)--; +#else + pthread_mutex_unlock(mutex); +#endif /* OS_DEP */ +} + diff --git a/src/flute_lib/flute_lock.h b/src/flute_lib/flute_lock.h new file mode 100644 index 0000000..cf51097 --- /dev/null +++ b/src/flute_lib/flute_lock.h @@ -0,0 +1,35 @@ +/* $Id: flute_lock.h,v 1.2 2005/05/12 16:03:44 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * (main author: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * OS dependant code + */ + +/* + * thread management functions and types + */ + + +extern void flute_init_lock (flute_mutex_t *mutex); +extern void flute_lock (flute_mutex_t *mutex); +extern int flute_trylock (flute_mutex_t *mutex); +extern void flute_unlock (flute_mutex_t *mutex); diff --git a/src/flute_lib/flute_md5.cpp b/src/flute_lib/flute_md5.cpp new file mode 100644 index 0000000..c3d4f79 --- /dev/null +++ b/src/flute_lib/flute_md5.cpp @@ -0,0 +1,84 @@ +/* $Id: flute_md5.cpp,v 1.2 2005/05/12 16:03:44 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * flute_md5.c + * + * Tools for md5 manipulations... + */ + +#include "flute_includes.h" + +#ifdef OPENSSL /* { */ +/* MD5sum */ + +#include +#include +#include + + +void base64enc(char *inbuffer, char ** outbuffer) +{ + + BIO *mbio,*b64bio,*bio; + char *p; + + mbio=BIO_new(BIO_s_mem()); + b64bio=BIO_new(BIO_f_base64()); + bio=BIO_push(b64bio,mbio); + + BIO_write(bio,inbuffer,MD5_DIGEST_LENGTH); + + BIO_flush(bio); + + BIO_ctrl(mbio,BIO_CTRL_INFO,0,(char *)&p); + + memcpy(*outbuffer,p,MD5BASE64_LENGTH); + + BIO_free_all(bio); + +} + + +void md5sum_calculate(int fd, unsigned char ** digest) +{ + unsigned char buf[1024]; + MD5_CTX ctx; + int n; + unsigned char *md5_digest = (unsigned char*)calloc(1, MD5_DIGEST_LENGTH); + + lseek(fd, 0, SEEK_SET); /*rewind*/ + + MD5_Init(&ctx); + + while ((n = read(fd, buf, sizeof(buf))) > 0) + MD5_Update(&ctx, buf, n); + MD5_Final(md5_digest, &ctx); + + base64enc((char *) md5_digest,(char **) digest); + + free(md5_digest); +} + +#endif /* } */ diff --git a/src/flute_lib/flute_md5.h b/src/flute_lib/flute_md5.h new file mode 100644 index 0000000..e49bff0 --- /dev/null +++ b/src/flute_lib/flute_md5.h @@ -0,0 +1,36 @@ +/* $Id: flute_md5.h,v 1.2 2005/05/12 16:03:44 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +/* + * flute_md5.h + * + * Tools for md5 manipulations... + */ + +#define MD5BASE64_LENGTH 24 + +#ifdef OPENSSL + +void md5sum_calculate(int fd, unsigned char ** digest); + +#endif diff --git a/src/flute_lib/macros.h b/src/flute_lib/macros.h new file mode 100644 index 0000000..dee5aca --- /dev/null +++ b/src/flute_lib/macros.h @@ -0,0 +1,68 @@ +/* $Id: macros.h,v 1.2 2005/05/12 16:03:45 moi Exp $ */ +/* + * Copyright (c) 2003-2004 INRIA - All rights reserved + * main authors: Christoph Neumann - christoph.neumann@inrialpes.fr + * Vincent Roca - vincent.roca@inrialpes.fr + * Julien Laboure - julien.laboure@inrialpes.fr + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#ifndef MACROS_H +#define MACROS_H + +#include + + +/****** general macros ******/ + +#ifndef min +#define min(a,b) ((a) <= (b) ? (a) : (b)) +#endif +#ifndef max +#define max(a,b) ((a) >= (b) ? (a) : (b)) +#endif + +/* + * print to stdout + */ +#define PRINT(a) { printf a; fflush(stdout); } + +/* + * print and exit + */ +#define EXIT(a) { printf a; fflush(stdout); exit(-1); } + +/* + * test, print and exit if error (i.e. if != 0) + */ +#define EXIT_ON_ERROR(err, a) { if (err) { EXIT(a) } } + + +#define ASSERT(c) { \ + if (!(c)) { \ + fprintf(stderr, "ASSERT [%s:%d] failed\n", \ + __FILE__, __LINE__); \ + fflush(stderr); \ + exit (-1); \ + } \ + } + +#define BUFFER_TO_INT32(x) ((*(x)<<24) + (*(x+1)<<16) + (*(x+2)<<8) + (*(x+3))) + + +#endif diff --git a/src/norm/Makefile b/src/norm/Makefile new file mode 100644 index 0000000..f970726 --- /dev/null +++ b/src/norm/Makefile @@ -0,0 +1,503 @@ +# $Id: Makefile,v 1.22 2005/03/23 14:05:04 roca Exp $ +# +# Makefile +# + +###### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Makefile.common as appropriate +include ../../Makefile.common + + +ifeq (${OS},linux) + # Linux version + # A few libs for memory debug: + # -lefence for memory debug on Linux (and other plateforms) + # Requires: export EF_PROTECT_FREE=1 + # export EF_PROTECT_BELOW=1 + # + #LIBRARIES = -Wl,-Bstatic -lefence -Wl,-Bdynamic -lc -lm -lpthread + LIBRARIES = -lc -lm -lpthread + BINDIR = ../../bin/linux + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},solaris) + # Solaris version: requires -lsocket -lnsl and -L/usr/ucblib -lucb + # + LIBRARIES = -lc -lm -lsocket -lnsl -L/usr/ucblib -lucb -lpthread + BINDIR = ../../bin/solaris + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + +ifeq (${OS},freebsd) + # FreeBSD version + BINDIR = ../../bin/freebsd + LDPC_BINDIR = ../../../ldpc/bin/freebsd + LIBRARIES = -lm -pthread + # TBC + LARGEFILE_FLAGS = -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE +endif + + +###### Other Variables ###### + +# Common source files are here... +COMMON_DIR = ../common/ + +# List of source, object and include files +# +SRCFILES = ${COMMON_DIR}/mcl_addr.cpp ${COMMON_DIR}/mcl_debug.cpp ${COMMON_DIR}/mcl_itime.cpp ${COMMON_DIR}/mcl_osdep.cpp ${COMMON_DIR}/rse_fec.cpp ${COMMON_DIR}/mcl_periodic_timer.cpp mcl.cpp mcl_cb.cpp mcl_lib.cpp mcl_adu.cpp mcl_block.cpp mcl_du.cpp mcl_fec.cpp mcl_fsm.cpp mcl_group_mgmt.cpp mcl_node.cpp mcl_timer.cpp mcl_periodic_proc.cpp mcl_ses_channel.cpp mcl_tx.cpp mcl_tx_window.cpp mcl_tx_storage.cpp mcl_tx_ctrl.cpp mcl_rx.cpp mcl_rx_thread.cpp mcl_rx_window.cpp mcl_rx_storage.cpp mcl_rx_ctrl.cpp mcl_stats.cpp mcl_norm_pkt_mgmt.cpp +OFILES = ${SRCFILES:.cpp=.o} + + +# General purpose local FLAGS. +# WARNING: with gcc/g++, never use -O3 optimisation (compiler bugs) +# +#CFLAGS = -DNORM ${OSFLAGS} ${LARGEFILE_FLAGS} -DDEBUG -g -fcheck-memory-usage +CFLAGS = -DNORM ${OSFLAGS} ${LARGEFILE_FLAGS} -DDEBUG -g # debug version +#CFLAGS = -DNORM ${OSFLAGS} ${LARGEFILE_FLAGS} -O -g # optimized +#CFLAGS = -DNORM ${OSFLAGS} ${LARGEFILE_FLAGS} -O -g -pg # optimized with profiling + +LDFLAGS = + + +###### Dependancies ###### +# by default, create the MCL lib +all: lib + +# Rule for C++ .cpp extension +.cpp.o: + $(CC) -c $(CFLAGS) -o $*.o $*.cpp + + +lib: ${OFILES} + @echo "** Now create the MCL-NORM library..." + ${AR} -rcsv ${BINDIR}/libmclnorm.a ${OFILES} + ${RANLIB} ${BINDIR}/libmclnorm.a + @echo "done" + +tags: + etags $(SRCS) + +clean: + @for f in core ${OFILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall: clean + @for f in ${BINDIR}/libmclnorm*.a ; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done + +depend: + # Use -Y to prevent including the system header files that won't + # change. Send all error messages to /dev/null + ${DEPEND} -- ${CFLAGS} -Y -- ${SRCFILES} 2>/dev/null + + +# Dependencies automatically created by makedepend (see depend target above). +# +# DO NOT DELETE THIS LINE -- make depend depends on it. + +../common//mcl_addr.o: ../norm/mcl_includes.h ../common/mcl_types.h +../common//mcl_addr.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_addr.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_addr.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +../common//mcl_addr.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_addr.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_addr.o: ../common/mcl_list.h ../common/rse_fec.h mcl.h +../common//mcl_addr.o: mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +../common//mcl_addr.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +../common//mcl_addr.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +../common//mcl_addr.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h +../common//mcl_addr.o: mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +../common//mcl_addr.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +../common//mcl_addr.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +../common//mcl_addr.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +../common//mcl_debug.o: ../norm/mcl_includes.h ../common/mcl_types.h +../common//mcl_debug.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_debug.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_debug.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +../common//mcl_debug.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_debug.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_debug.o: ../common/mcl_list.h ../common/rse_fec.h mcl.h +../common//mcl_debug.o: mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +../common//mcl_debug.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +../common//mcl_debug.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +../common//mcl_debug.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h +../common//mcl_debug.o: mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +../common//mcl_debug.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +../common//mcl_debug.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +../common//mcl_debug.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +../common//mcl_itime.o: ../norm/mcl_includes.h ../common/mcl_types.h +../common//mcl_itime.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_itime.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_itime.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +../common//mcl_itime.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_itime.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_itime.o: ../common/mcl_list.h ../common/rse_fec.h mcl.h +../common//mcl_itime.o: mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +../common//mcl_itime.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +../common//mcl_itime.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +../common//mcl_itime.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h +../common//mcl_itime.o: mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +../common//mcl_itime.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +../common//mcl_itime.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +../common//mcl_itime.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +../common//mcl_osdep.o: ../norm/mcl_includes.h ../common/mcl_types.h +../common//mcl_osdep.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_osdep.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +../common//mcl_osdep.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +../common//mcl_osdep.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_osdep.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_osdep.o: ../common/mcl_list.h ../common/rse_fec.h mcl.h +../common//mcl_osdep.o: mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +../common//mcl_osdep.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +../common//mcl_osdep.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +../common//mcl_osdep.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h +../common//mcl_osdep.o: mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +../common//mcl_osdep.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +../common//mcl_osdep.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +../common//mcl_osdep.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +../common//rse_fec.o: ../common/mcl_debug.h +../common//mcl_periodic_timer.o: ../norm/mcl_includes.h ../common/mcl_types.h +../common//mcl_periodic_timer.o: ../common/mcl_osdep.h mcl_profile.h +../common//mcl_periodic_timer.o: ../common/mcl_defines.h +../common//mcl_periodic_timer.o: ../common/mcl_lib_api.h +../common//mcl_periodic_timer.o: ../common/mcl_types.h +../common//mcl_periodic_timer.o: ../norm/mcl_lib_api_norm.h +../common//mcl_periodic_timer.o: ../common/mcl_version.h ../common/mcl_addr.h +../common//mcl_periodic_timer.o: ../common/mcl_debug.h ../common/mcl_itime.h +../common//mcl_periodic_timer.o: ../common/mcl_list.h ../common/rse_fec.h +../common//mcl_periodic_timer.o: mcl.h mcl_norm_hdr.h mcl_adu.h +../common//mcl_periodic_timer.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h +../common//mcl_periodic_timer.o: mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +../common//mcl_periodic_timer.o: mcl_timer_handler.h +../common//mcl_periodic_timer.o: ../common/mcl_periodic_timer.h +../common//mcl_periodic_timer.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h +../common//mcl_periodic_timer.o: mcl_ses_channel.h mcl_tx.h +../common//mcl_periodic_timer.o: mcl_lib_api_norm.h mcl_tx_window.h +../common//mcl_periodic_timer.o: mcl_tx_ctrl.h mcl_tx_storage.h +../common//mcl_periodic_timer.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +../common//mcl_periodic_timer.o: mcl_rx_thread.h mcl_rx_ctrl.h +../common//mcl_periodic_timer.o: mcl_rx_storage.h +mcl.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl.o: ../common/mcl_version.h ../common/mcl_addr.h ../common/mcl_debug.h +mcl.o: ../common/mcl_itime.h ../common/mcl_list.h ../common/rse_fec.h mcl.h +mcl.o: mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h +mcl.o: mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h mcl_group_mgmt.h +mcl.o: mcl_rx.h mcl_rx_window.h mcl_rx_thread.h mcl_rx_ctrl.h +mcl.o: mcl_rx_storage.h +mcl_cb.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_cb.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_cb.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_cb.o: ../common/mcl_version.h ../common/mcl_addr.h ../common/mcl_debug.h +mcl_cb.o: ../common/mcl_itime.h ../common/mcl_list.h ../common/rse_fec.h +mcl_cb.o: mcl.h mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_cb.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_cb.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_cb.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h mcl_ses_channel.h +mcl_cb.o: mcl_tx.h mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_cb.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_cb.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_lib.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_lib.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_lib.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_lib.o: ../common/mcl_version.h ../common/mcl_addr.h ../common/mcl_debug.h +mcl_lib.o: ../common/mcl_itime.h ../common/mcl_list.h ../common/rse_fec.h +mcl_lib.o: mcl.h mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_lib.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_lib.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_lib.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h mcl_ses_channel.h +mcl_lib.o: mcl_tx.h mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_lib.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_lib.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_adu.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_adu.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_adu.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_adu.o: ../common/mcl_version.h ../common/mcl_addr.h ../common/mcl_debug.h +mcl_adu.o: ../common/mcl_itime.h ../common/mcl_list.h ../common/rse_fec.h +mcl_adu.o: mcl.h mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_adu.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_adu.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_adu.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h mcl_ses_channel.h +mcl_adu.o: mcl_tx.h mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_adu.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_adu.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_block.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_block.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_block.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_block.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_block.o: ../common/mcl_debug.h ../common/mcl_itime.h ../common/mcl_list.h +mcl_block.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_block.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h mcl_node.h +mcl_block.o: mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_block.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl_block.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_block.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h mcl_group_mgmt.h +mcl_block.o: mcl_rx.h mcl_rx_window.h mcl_rx_thread.h mcl_rx_ctrl.h +mcl_block.o: mcl_rx_storage.h +mcl_du.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_du.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_du.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_du.o: ../common/mcl_version.h ../common/mcl_addr.h ../common/mcl_debug.h +mcl_du.o: ../common/mcl_itime.h ../common/mcl_list.h ../common/rse_fec.h +mcl_du.o: mcl.h mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_du.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_du.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_du.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h mcl_ses_channel.h +mcl_du.o: mcl_tx.h mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_du.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_du.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_fec.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_fec.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_fec.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_fec.o: ../common/mcl_version.h ../common/mcl_addr.h ../common/mcl_debug.h +mcl_fec.o: ../common/mcl_itime.h ../common/mcl_list.h ../common/rse_fec.h +mcl_fec.o: mcl.h mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_fec.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_fec.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_fec.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h mcl_ses_channel.h +mcl_fec.o: mcl_tx.h mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_fec.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_fec.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_fsm.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_fsm.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_fsm.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_fsm.o: ../common/mcl_version.h ../common/mcl_addr.h ../common/mcl_debug.h +mcl_fsm.o: ../common/mcl_itime.h ../common/mcl_list.h ../common/rse_fec.h +mcl_fsm.o: mcl.h mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_fsm.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_fsm.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_fsm.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h mcl_ses_channel.h +mcl_fsm.o: mcl_tx.h mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_fsm.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_fsm.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_group_mgmt.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_group_mgmt.o: mcl_profile.h ../common/mcl_defines.h +mcl_group_mgmt.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_group_mgmt.o: ../norm/mcl_lib_api_norm.h ../common/mcl_version.h +mcl_group_mgmt.o: ../common/mcl_addr.h ../common/mcl_debug.h +mcl_group_mgmt.o: ../common/mcl_itime.h ../common/mcl_list.h +mcl_group_mgmt.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_group_mgmt.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h +mcl_group_mgmt.o: mcl_node.h mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_group_mgmt.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h +mcl_group_mgmt.o: mcl_fec.h mcl_stats.h mcl_ses_channel.h mcl_tx.h +mcl_group_mgmt.o: mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_group_mgmt.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_group_mgmt.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_node.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_node.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_node.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_node.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_node.o: ../common/mcl_debug.h ../common/mcl_itime.h ../common/mcl_list.h +mcl_node.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_node.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h mcl_node.h +mcl_node.o: mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_node.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl_node.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_node.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h mcl_group_mgmt.h +mcl_node.o: mcl_rx.h mcl_rx_window.h mcl_rx_thread.h mcl_rx_ctrl.h +mcl_node.o: mcl_rx_storage.h +mcl_timer.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_timer.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_timer.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_timer.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_timer.o: ../common/mcl_debug.h ../common/mcl_itime.h ../common/mcl_list.h +mcl_timer.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_timer.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h mcl_node.h +mcl_timer.o: mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_timer.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl_timer.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_timer.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h mcl_group_mgmt.h +mcl_timer.o: mcl_rx.h mcl_rx_window.h mcl_rx_thread.h mcl_rx_ctrl.h +mcl_timer.o: mcl_rx_storage.h +mcl_periodic_proc.o: mcl_includes.h ../common/mcl_types.h +mcl_periodic_proc.o: ../common/mcl_osdep.h mcl_profile.h +mcl_periodic_proc.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_periodic_proc.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_periodic_proc.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_periodic_proc.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_periodic_proc.o: ../common/mcl_list.h ../common/rse_fec.h mcl.h +mcl_periodic_proc.o: mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_periodic_proc.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_periodic_proc.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_periodic_proc.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h +mcl_periodic_proc.o: mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_periodic_proc.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +mcl_periodic_proc.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_periodic_proc.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_ses_channel.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_ses_channel.o: mcl_profile.h ../common/mcl_defines.h +mcl_ses_channel.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_ses_channel.o: ../norm/mcl_lib_api_norm.h ../common/mcl_version.h +mcl_ses_channel.o: ../common/mcl_addr.h ../common/mcl_debug.h +mcl_ses_channel.o: ../common/mcl_itime.h ../common/mcl_list.h +mcl_ses_channel.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_ses_channel.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h +mcl_ses_channel.o: mcl_node.h mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_ses_channel.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h +mcl_ses_channel.o: mcl_fec.h mcl_stats.h mcl_ses_channel.h mcl_tx.h +mcl_ses_channel.o: mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_ses_channel.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_ses_channel.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_tx.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_tx.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_tx.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_tx.o: ../common/mcl_version.h ../common/mcl_addr.h ../common/mcl_debug.h +mcl_tx.o: ../common/mcl_itime.h ../common/mcl_list.h ../common/rse_fec.h +mcl_tx.o: mcl.h mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_tx.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_tx.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_tx.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h mcl_ses_channel.h +mcl_tx.o: mcl_tx.h mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_tx.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_tx.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_tx_window.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_tx_window.o: mcl_profile.h ../common/mcl_defines.h +mcl_tx_window.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_tx_window.o: ../norm/mcl_lib_api_norm.h ../common/mcl_version.h +mcl_tx_window.o: ../common/mcl_addr.h ../common/mcl_debug.h +mcl_tx_window.o: ../common/mcl_itime.h ../common/mcl_list.h +mcl_tx_window.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_tx_window.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h mcl_node.h +mcl_tx_window.o: mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_tx_window.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl_tx_window.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_tx_window.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +mcl_tx_window.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h mcl_rx_thread.h +mcl_tx_window.o: mcl_rx_ctrl.h mcl_rx_storage.h +mcl_tx_storage.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_tx_storage.o: mcl_profile.h ../common/mcl_defines.h +mcl_tx_storage.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_tx_storage.o: ../norm/mcl_lib_api_norm.h ../common/mcl_version.h +mcl_tx_storage.o: ../common/mcl_addr.h ../common/mcl_debug.h +mcl_tx_storage.o: ../common/mcl_itime.h ../common/mcl_list.h +mcl_tx_storage.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_tx_storage.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h +mcl_tx_storage.o: mcl_node.h mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_tx_storage.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h +mcl_tx_storage.o: mcl_fec.h mcl_stats.h mcl_ses_channel.h mcl_tx.h +mcl_tx_storage.o: mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_tx_storage.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_tx_storage.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_tx_ctrl.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_tx_ctrl.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_tx_ctrl.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_tx_ctrl.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_tx_ctrl.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_tx_ctrl.o: ../common/mcl_list.h ../common/rse_fec.h mcl.h mcl_norm_hdr.h +mcl_tx_ctrl.o: mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h +mcl_tx_ctrl.o: mcl_node.h mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_tx_ctrl.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl_tx_ctrl.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_tx_ctrl.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +mcl_tx_ctrl.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h mcl_rx_thread.h +mcl_tx_ctrl.o: mcl_rx_ctrl.h mcl_rx_storage.h +mcl_rx.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_rx.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_rx.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_rx.o: ../common/mcl_version.h ../common/mcl_addr.h ../common/mcl_debug.h +mcl_rx.o: ../common/mcl_itime.h ../common/mcl_list.h ../common/rse_fec.h +mcl_rx.o: mcl.h mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_rx.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_rx.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_rx.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h mcl_ses_channel.h +mcl_rx.o: mcl_tx.h mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_rx.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_rx.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_rx_thread.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_rx_thread.o: mcl_profile.h ../common/mcl_defines.h +mcl_rx_thread.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_rx_thread.o: ../norm/mcl_lib_api_norm.h ../common/mcl_version.h +mcl_rx_thread.o: ../common/mcl_addr.h ../common/mcl_debug.h +mcl_rx_thread.o: ../common/mcl_itime.h ../common/mcl_list.h +mcl_rx_thread.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_rx_thread.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h mcl_node.h +mcl_rx_thread.o: mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_rx_thread.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl_rx_thread.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_rx_thread.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +mcl_rx_thread.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h mcl_rx_thread.h +mcl_rx_thread.o: mcl_rx_ctrl.h mcl_rx_storage.h +mcl_rx_window.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_rx_window.o: mcl_profile.h ../common/mcl_defines.h +mcl_rx_window.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_rx_window.o: ../norm/mcl_lib_api_norm.h ../common/mcl_version.h +mcl_rx_window.o: ../common/mcl_addr.h ../common/mcl_debug.h +mcl_rx_window.o: ../common/mcl_itime.h ../common/mcl_list.h +mcl_rx_window.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_rx_window.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h mcl_node.h +mcl_rx_window.o: mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_rx_window.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl_rx_window.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_rx_window.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +mcl_rx_window.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h mcl_rx_thread.h +mcl_rx_window.o: mcl_rx_ctrl.h mcl_rx_storage.h +mcl_rx_storage.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_rx_storage.o: mcl_profile.h ../common/mcl_defines.h +mcl_rx_storage.o: ../common/mcl_lib_api.h ../common/mcl_types.h +mcl_rx_storage.o: ../norm/mcl_lib_api_norm.h ../common/mcl_version.h +mcl_rx_storage.o: ../common/mcl_addr.h ../common/mcl_debug.h +mcl_rx_storage.o: ../common/mcl_itime.h ../common/mcl_list.h +mcl_rx_storage.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_rx_storage.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h +mcl_rx_storage.o: mcl_node.h mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_rx_storage.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h +mcl_rx_storage.o: mcl_fec.h mcl_stats.h mcl_ses_channel.h mcl_tx.h +mcl_rx_storage.o: mcl_lib_api_norm.h mcl_tx_window.h mcl_tx_ctrl.h +mcl_rx_storage.o: mcl_tx_storage.h mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_rx_storage.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h +mcl_rx_ctrl.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_rx_ctrl.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_rx_ctrl.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_rx_ctrl.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_rx_ctrl.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_rx_ctrl.o: ../common/mcl_list.h ../common/rse_fec.h mcl.h mcl_norm_hdr.h +mcl_rx_ctrl.o: mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h +mcl_rx_ctrl.o: mcl_node.h mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_rx_ctrl.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl_rx_ctrl.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_rx_ctrl.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +mcl_rx_ctrl.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h mcl_rx_thread.h +mcl_rx_ctrl.o: mcl_rx_ctrl.h mcl_rx_storage.h +mcl_stats.o: mcl_includes.h ../common/mcl_types.h ../common/mcl_osdep.h +mcl_stats.o: mcl_profile.h ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_stats.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_stats.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_stats.o: ../common/mcl_debug.h ../common/mcl_itime.h ../common/mcl_list.h +mcl_stats.o: ../common/rse_fec.h mcl.h mcl_norm_hdr.h mcl_adu.h +mcl_stats.o: mcl_norm_pkt_mgmt.h mcl_du.h mcl_block.h mcl_cb.h mcl_node.h +mcl_stats.o: mcl_fsm.h mcl_timer.h mcl_timer_handler.h +mcl_stats.o: ../common/mcl_periodic_timer.h mcl_periodic_proc.h mcl_fec.h +mcl_stats.o: mcl_stats.h mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_stats.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h mcl_group_mgmt.h +mcl_stats.o: mcl_rx.h mcl_rx_window.h mcl_rx_thread.h mcl_rx_ctrl.h +mcl_stats.o: mcl_rx_storage.h +mcl_norm_pkt_mgmt.o: mcl_includes.h ../common/mcl_types.h +mcl_norm_pkt_mgmt.o: ../common/mcl_osdep.h mcl_profile.h +mcl_norm_pkt_mgmt.o: ../common/mcl_defines.h ../common/mcl_lib_api.h +mcl_norm_pkt_mgmt.o: ../common/mcl_types.h ../norm/mcl_lib_api_norm.h +mcl_norm_pkt_mgmt.o: ../common/mcl_version.h ../common/mcl_addr.h +mcl_norm_pkt_mgmt.o: ../common/mcl_debug.h ../common/mcl_itime.h +mcl_norm_pkt_mgmt.o: ../common/mcl_list.h ../common/rse_fec.h mcl.h +mcl_norm_pkt_mgmt.o: mcl_norm_hdr.h mcl_adu.h mcl_norm_pkt_mgmt.h mcl_du.h +mcl_norm_pkt_mgmt.o: mcl_block.h mcl_cb.h mcl_node.h mcl_fsm.h mcl_timer.h +mcl_norm_pkt_mgmt.o: mcl_timer_handler.h ../common/mcl_periodic_timer.h +mcl_norm_pkt_mgmt.o: mcl_periodic_proc.h mcl_fec.h mcl_stats.h +mcl_norm_pkt_mgmt.o: mcl_ses_channel.h mcl_tx.h mcl_lib_api_norm.h +mcl_norm_pkt_mgmt.o: mcl_tx_window.h mcl_tx_ctrl.h mcl_tx_storage.h +mcl_norm_pkt_mgmt.o: mcl_group_mgmt.h mcl_rx.h mcl_rx_window.h +mcl_norm_pkt_mgmt.o: mcl_rx_thread.h mcl_rx_ctrl.h mcl_rx_storage.h diff --git a/src/norm/mcl.cpp b/src/norm/mcl.cpp new file mode 100644 index 0000000..e369d59 --- /dev/null +++ b/src/norm/mcl.cpp @@ -0,0 +1,207 @@ +/* $Id: mcl.cpp,v 1.5 2004/05/26 12:54:56 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/****** definition of global MCL variables ******/ + +/* MCL version of standard streams. */ +FILE *mcl_stdout; /* MCL standard output stream */ +FILE *mcl_stderr; /* MCL standard error output stream */ + +char mcl_tmp_dir_name[MAX_FILE_NAME_LEN]; + +const UINT32 mcl_iss = 1; +UINT32 mcl_time_count; + +mcl_periodic_timer mcl_periodic_timer_obj; + + +/****** local static variables ******/ + + +/** + * Return the version # and credits. + * Edit as appropriate... + */ +void +mcl_moreabout (void) +{ + // + // credits (very important :-) + // + PRINT_OUT((mcl_stdout, "\n-- MultiCast Library (MCL) for the NORM reliable multicast protocol --\n")) + PRINT_OUT((mcl_stdout, MCLv3_VERSION)) + PRINT_OUT((mcl_stdout, " Copyright (c) 2003-2004 INRIA - All rights reserved\n")) + PRINT_OUT((mcl_stdout, " main author/contact: vincent.roca@inrialpes.fr\n")) + PRINT_OUT((mcl_stdout, " web site: http://www.inrialpes.fr/planete/people/roca/mcl/\n")) + PRINT_OUT((mcl_stdout, " MCL comes with ABSOLUTELY NO WARRANTY; This is free software,\n")) + PRINT_OUT((mcl_stdout, " and you are welcome to redistribute it under certain conditions;\n")) + PRINT_OUT((mcl_stdout, " See the GNU Lesser General Public License as published by the Free \n")) + PRINT_OUT((mcl_stdout, " Software Foundation, version 2.1 or later, for more details.\n")) + PRINT_OUT((mcl_stdout, "-- Credits:\n")) + PRINT_OUT((mcl_stdout, "* Vincent Roca (INRIA R.A.)\n")) +#ifdef RSE_FEC + PRINT_OUT((mcl_stdout, "* fec.c -- forward error corection based on Vandermonde matrices\n")) + PRINT_OUT((mcl_stdout, " (C) 1997-98 Luigi Rizzo (luigi@iet.unipi.it) (980624)\n")) + PRINT_OUT((mcl_stdout, " Portions derived from code by Phil Karn (karn@ka9q.ampr.org),\n")) + PRINT_OUT((mcl_stdout, " Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and\n")) + PRINT_OUT((mcl_stdout, " Hari Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995\n")) +#endif + PRINT_OUT((mcl_stdout, "* This product includes software developed by TASC, Inc. and the\n")) + PRINT_OUT((mcl_stdout, " University of Massachusetts at Amherst.\n")) + //PRINT_OUT((mcl_stdout, " Copyright (c) 1997-2001 TASC, Inc.\n")) + //PRINT_OUT((mcl_stdout, " Copyright (c) 1997-2001 University of Massachusetts at Amherst.\n")) + + // + // compilation options + // + PRINT_OUT((mcl_stdout, "-- Compiled with:\n ")) +#ifdef INET6 + PRINT_OUT((mcl_stdout, "INET6 ")) +#endif + +#ifdef RSE_FEC + PRINT_OUT((mcl_stdout, "RSE_FEC ")) +#endif + +#ifdef DEBUG + PRINT_OUT((mcl_stdout, "DEBUG ")) +#endif + +#ifdef SIMUL_TX_LOSSES + PRINT_OUT((mcl_stdout, "!!!SIMUL_TX_LOSSES!!! ")) +#endif + +#ifdef SIMUL_RX_LOSSES + PRINT_OUT((mcl_stdout, "!!!SIMUL_RX_LOSSES!!! ")) +#endif + PRINT_OUT((mcl_stdout, "\n")) +} + + +/** + * emergency exit function. + * do as little as possible as we are in an unknown state... + * @param n int to be returned by exit() + */ +void +mcl_exit (int n) +{ + int id; + mcl_cb *mclcb = NULL; + + PRINT_ERR((mcl_stderr, "mcl_exit: ERROR, exit everything...\n")) +#if 0 + /* find the first valid mclcb first */ + for (id = 0; id < MAX_NB_MCLCB; id++) { + if (mclcb_tab[id] != NULL) { + mclcb = mclcb_tab[id]; + break; + } + } +#endif + exit(n); +} + + +/** + * new_handler function. + */ +static void +mcl_new_handler_func () +{ + PRINT_ERR((mcl_stderr, "mcl_new_handler_func: ERROR, no memory left, exit everything...\n")) + mcl_exit(-1); +} + + +/** + * Global MCL library initialization. + * Done only once. + */ +void +mcl_global_init (void) +{ + // for the one time MCL global initialization + static bool mcl_glob_initialized = false; + + if (mcl_glob_initialized == true) + return; + mcl_glob_initialized = true; + + set_new_handler(mcl_new_handler_func); + mcl_init_random(); + strcat(mcl_tmp_dir_name, MCL_DEFAULT_TMP_DIR_NAME); + + mcl_stdout_stderr_init(); + + /* initialize the session control block table */ + mcl_init_mclcb_tab(); + +#ifdef WIN32 + /* Socket initialisation for WinSock */ + mcl_winsock_init(); +#endif /* WIN32 */ + + /* create and start the global periodic timer service */ + mcl_periodic_timer_obj.start(); + + ASSERT(mcl_iss > 0); /* must be > 0 (0 means non initialized) */ +} + + +/** + * Initialize the mcl_stdout and mcl_stderr outputs. + * Assumes that the mcl_tmp_dir_name global variable is already initialized. + */ +void +mcl_stdout_stderr_init (void) +{ +#ifdef STDOUT_TO_FILE + char stdout_name[MAX_FILE_NAME_LEN]; +#endif + +#ifdef STDOUT_TO_FILE + memset(stdout_name, 0, MAX_FILE_NAME_LEN); + strncat(stdout_name, mcl_tmp_dir_name, MAX_FILE_NAME_LEN); + strncat(stdout_name, "/mcl_out.txt", MAX_FILE_NAME_LEN); + /* create temp file now in the tmp dir specified in mcl_tmp_dir_name */ +#ifdef WIN32 + if ((mcl_stdout = open(vcb->f_name, _O_RDWR | O_CREAT | O_BINARY)) < 0) { + perror("mcl_glob_init: ERROR, cannot open mlc_out.trc file"); + mcl_exit(-1); + } +#else /* UNIX case */ + if ((mcl_stdout = fopen(stdout_name, "w")) == NULL) { +printf("error: cannot open %s\n", stdout_name); + perror("mcl_glob_init: ERROR, cannot open mlc_out.trc file"); + mcl_exit(-1); + } +#endif /* OS */ + mcl_stderr = mcl_stdout; /* err is the same then */ +#else /* STDOUT_TO_FILE */ + mcl_stdout = stdout; + mcl_stderr = stderr; +#endif /* STDOUT_TO_FILE */ +} + diff --git a/src/norm/mcl.h b/src/norm/mcl.h new file mode 100644 index 0000000..1701c5d --- /dev/null +++ b/src/norm/mcl.h @@ -0,0 +1,60 @@ +/* $Id: mcl.h,v 1.5 2004/06/15 15:53:27 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_H +#define MCL_H + +/****** general purpose enumerations ******************************************/ + +/** + * Used to differentiate between sending and receiving variants when needed. + */ +enum mcl_tx_or_rx { + MCL_TX, + MCL_RX +}; + + +/****** prototypes ************************************************************/ + +extern void mcl_moreabout (void); +extern void mcl_exit (int n); +extern void mcl_global_init (void); +extern void mcl_stdout_stderr_init (void); + + +/****** global variables shared by all sessions *******************************/ + +/* MCL version of standard streams */ +extern FILE *mcl_stdout; +extern FILE *mcl_stderr; + +extern const UINT32 mcl_iss; +extern UINT32 mcl_time_count; + +extern mcl_thread_t mcl_timer_thread_id; + +extern char mcl_tmp_dir_name[MAX_FILE_NAME_LEN]; + +extern class mcl_periodic_timer mcl_periodic_timer_obj; + + +#endif // MCL_H diff --git a/src/norm/mcl_ack.h b/src/norm/mcl_ack.h new file mode 100644 index 0000000..b67b4bc --- /dev/null +++ b/src/norm/mcl_ack.h @@ -0,0 +1,53 @@ +/* $Id: mcl_ack.h,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_ACK_H +#define MCL_ACK_H + +/** + * Class explanation + */ +class XXX { + +public: + /****** Public Members ************************************************/ + /****** Public Attributes *********************************************/ + + /** + * + * @param XXX explanation + * @return Completion status (MCL_OK or MCL_ERROR). + */ + +protected: + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +#endif // MCL_ACK_H diff --git a/src/norm/mcl_adu.cpp b/src/norm/mcl_adu.cpp new file mode 100644 index 0000000..6146e78 --- /dev/null +++ b/src/norm/mcl_adu.cpp @@ -0,0 +1,561 @@ +/* $Id: mcl_adu.cpp,v 1.4 2004/02/18 07:56:18 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * Default constructor USED BY THE SENDER. + */ +mcl_adu::mcl_adu (mcl_cb *const mclcb, + INT32 const alen, + mcl_addr const* saddr) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_adu::mcl_adu: TX, len=%d\n", len)) + memset(this, 0, sizeof(*this)); + this->type = MCL_TX; + this->len = alen; + this->tx_status = ADU_TSTATUS_IN_PROGRESS; + //this->data = NULL; + this->seq = mclcb->tx.get_seq_for_new_adu(); + if (saddr != NULL) { + // use the provided address + this->addr = *saddr; + } else { + // else use the default session addr + this->addr = mclcb->ses_channel.ses_addr; + } + // calculate and set the padded length + INT32 plen = (INT32) + (ceil((double)alen / (double)mclcb->get_payload_size()) + * (double)mclcb->get_payload_size()); + this->padded_len = plen; + TRACELVL(4, (mcl_stdout, " mcl_adu::mcl_adu: NEW ADU seq=%d, len =%d\n", + this->seq, this->len)) + TRACELVL(5, (mcl_stdout, "<- mcl_adu::mcl_adu:\n")) +} + + +/** + * Default constructor USED BY THE RECEIVER. + */ +mcl_adu::mcl_adu (mcl_cb *const mclcb, + mcl_data_hdr_infos_t const* dhdr_infos, + mcl_addr const* saddr) +{ + mcl_block *blk; + UINT32 rem; + UINT32 bseq; // block sequence number + + TRACELVL(5, (mcl_stdout, "-> mcl_adu::mcl_adu: RX\n")) + memset(this, 0, sizeof(*this)); + this->type = MCL_RX; + this->seq = dhdr_infos->idf_adu; + this->len = dhdr_infos->adu_len; + this->rx_status = ADU_STATUS_IN_PROGRESS; + //this->data = NULL; + if (saddr != NULL) { + // use the provided address + this->addr = *saddr; + } // else zero'ed address + /* + * NON-NORM-COMPLIANT: + * assume (1) block_len is for full-size block and (2) is in bytes + */ + this->full_size_block_len = dhdr_infos->block_len; + /* + * calculate the number of DUs for each block and + * allocate the block structs... + * do it simply: allocate a tab of block_t structs + * rather than a linked list! + */ + this->block_nb = (int)ceil((double)this->len / + (double)this->full_size_block_len); + blk = new mcl_block [this->block_nb];// no mcl_block default constructor + // for performance reasons! + ASSERT(blk); + memset(blk, 0, sizeof(mcl_block) * this->block_nb); + this->block_head = blk; + rem = this->len; + for (bseq = 0; (INT32)bseq < this->block_nb; bseq++, blk++) { + blk->set_rx_status(BLK_STATUS_IN_PROGRESS); + blk->adu = this; + blk->seq = bseq; + blk->len = min(rem, dhdr_infos->block_len); + blk->du_nb = (int)ceil((double)blk->len / + (double)mclcb->get_payload_size()); + /* + * blk->du_head, fec_du_head, fec_du_nb, du_rx + * already set to NULL/0 + */ + rem -= blk->len; + } + TRACELVL(1, (mcl_stdout, + "New ADU: seq=%d, len=%d, composed of %d blks at most %d bytes/%d DUs long\n", + this->seq, this->len, this->block_nb, + this->full_size_block_len, this->block_head->du_nb)) + TRACELVL(5, (mcl_stdout, "<- mcl_adu::mcl_adu:\n")) +} + + +/** + * Default destructor. + */ +mcl_adu::~mcl_adu () +{ + this->remove_and_free_all_buffers(NULL); +} + + +/** + */ +void +mcl_adu::remove_and_free_all_buffers (mcl_cb *const mclcb) +{ + UINT32 i; + mcl_block *blk; + + if (this->type == MCL_TX) { + /* Sender */ + /* TODO: check there are no remaining references to this adu */ + if (this->block_nb > 0) { + /* free FEC dus created in each block */ + for (i = this->block_nb, blk = this->block_head; + i > 0; i--, blk++) { + blk->remove_and_free_all_fec_dus (mclcb); + } + /* free all blk and du descriptors for this adu */ + ASSERT(this->block_head->get_du_head()); + delete [] this->block_head->get_du_head(); + this->block_head->set_du_head(NULL); + ASSERT(this->block_head); + delete [] this->block_head; + this->block_head = NULL; + this->block_nb = 0; + /* free buffer containing adu data */ + ASSERT(this->data); + free(this->data); + this->data = NULL; + } + } else { + /* Receiver */ + ASSERT(this->type == MCL_RX); + if (this->block_nb > 0) { + /* free all DUs in each block */ + for (i = this->block_nb, blk = this->block_head; + i > 0; i--, blk++) { + blk->remove_and_free_all_fec_dus (mclcb); + blk->remove_and_free_all_data_dus (mclcb); + } + /* free all blocks and du descriptors for this adu */ + ASSERT(this->block_head); + delete [] this->block_head; + this->block_head = NULL; + this->block_nb = 0; + this->set_tx_status(ADU_TSTATUS_DONE); + } else { + ASSERT(this->get_tx_status() == ADU_TSTATUS_DONE); + } + } +} + + +/** + * Check if this adu is JUST completed and take appropriate measures. + * Used by a receiver when a new non-duplicated du is received for + * a block. + * @param mclcb + * @return true if completed and appropriate measures taken, + * false otherwise. + */ +bool +mcl_adu::check_if_completed_and_process (mcl_cb *const mclcb) +{ + TRACELVL(5, (mcl_stdout, + "-> mcl_adu::check_if_completed_and_process:\n")) + if (this->check_if_just_completed(mclcb)) { + TRACELVL(1, (mcl_stdout, "End of ADU %d\n", this->seq)) + if (mclcb->get_stats_level() == 2) + mclcb->stats.print_rx_stats(mclcb); + if (!mclcb->rx_window.postpone_fec_decoding && + this->rx_status == ADU_STATUS_COMPLETED) { + /* do not wait, decode every block of this adu */ + if (this->decode_all_blocks(mclcb) == MCL_ERROR) { + mcl_exit(-1); + } + } + mclcb->rx_window.mark_ready_adu(); + if (mclcb->fsm.no_new_adu(mclcb) && + mclcb->rx_window.check_if_all_adu_completed(mclcb)) { + /* + * we know we won't receive any new ADU and + * it was the last packet we were waiting for... + */ + TRACELVL(1, (mcl_stdout, "All ADUs received\n")) + mclcb->fsm.update_rx_state(mclcb, REVENT_ALL_DU_RECV); + if (mclcb->get_stats_level() >= 1) { + mclcb->stats.print_rx_stats(mclcb); + mclcb->stats.print_final_stats(mclcb); + } +#if 0 + /* + * unsubscribe to all layers (incl. layer 0) to avoid + * receiving useless packets + */ + mcl_drop_layer(mclcb, MCL_ALL_LAYERS, MCL_DO_IT); + /* + * we can now decode all ADUs if in postpone mode + */ + if (mclcb->postpone_fec_decoding) { + mcl_decode_all_adu(mclcb); + } +#endif + } + TRACELVL(5, (mcl_stdout, + "<- mcl_adu::check_if_completed_and_process: yes\n")) + return true; + } else { + TRACELVL(5, (mcl_stdout, + "<- mcl_adu::check_if_completed_and_process: no\n")) + return false; + } +} + + +/* + * @returns true if the adu has JUST been completely received (decoded + * or not), false otherwise. + */ +bool +mcl_adu::check_if_just_completed (mcl_cb *const mclcb) +{ + mcl_block *blk; + INT32 i; + mcl_adu_rx_status new_status; + + TRACELVL(5, (mcl_stdout, "-> mcl_adu::check_if_just_completed:\n")) + if (this->rx_status >= ADU_STATUS_COMPLETED) { + /* in COMPLETED, DECODED, or DELIVERED mode */ + /* we have already recvd everything */ + TRACELVL(5, (mcl_stdout, "<- mcl_adu::check_if_just_completed: already completed\n")) + return false; + } + new_status = ADU_STATUS_DECODED; + for (i = this->block_nb, blk = this->block_head; i > 0; i--, blk++) { + if (blk->get_rx_status() != BLK_STATUS_COMPLETED && + blk->get_rx_status() != BLK_STATUS_DECODED) { + TRACELVL(5, (mcl_stdout, "<- mcl_adu::check_if_just_completed: no\n")) + return false; + } + if (blk->get_rx_status() == BLK_STATUS_COMPLETED) { + /* at least one blk is not decoded, remember it */ + new_status = ADU_STATUS_COMPLETED; + } + //if (i == 1) { + // /* we have cycled, yes this is a new completed ADU! */ + // break; + //} + } + /* + * we have everything. Update status and stats... + */ + this->rx_status = new_status; + mclcb->stats.finish_times[mclcb->stats.finish_index][STATS_FIN_TIME] = mcl_time_count; + mclcb->stats.finish_times[mclcb->stats.finish_index][STATS_SEQ] = this->seq; + if (++(mclcb->stats.finish_index) == MAX_FIN_TIME) + mclcb->stats.finish_index = 0; + mclcb->stats.adus_completed++; + TRACELVL(5, (mcl_stdout, "<- mcl_adu::check_if_just_completed: yes\n")) + return true; +} + + +/** + * Decode all the block of an ADU. + */ +mcl_error_status +mcl_adu::decode_all_blocks (mcl_cb *const mclcb) +{ + mcl_block *blk; + int i; + + ASSERT(this->rx_status == ADU_STATUS_COMPLETED) + for (i = this->block_nb, blk = this->block_head; i > 0; i--, blk++) { + if (blk->get_rx_status() == BLK_STATUS_DECODED) + continue; + if (mclcb->fec.decode(mclcb, blk) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_adu::decode_all_blocks: ERROR, decode failed\n")) + return MCL_ERROR; + } + } +#ifdef GET_SYSINFO + mcl_print_sysinfo(mclcb); +#endif + this->rx_status = ADU_STATUS_DECODED; + return MCL_OK; +} + + +mcl_error_status +mcl_adu::insert_in_list (mcl_cb *const mclcb, + mcl_adu **head) +{ + mcl_adu *adul; // temp pointer to adus currently in the list + + ASSERT(head); + TRACELVL(5, (mcl_stdout, + "-> mcl_adu::insert_in_list: adu=x%x, seq=%d\n", + (int)this, this->seq)) + if (!(*head)) { + /* + * first adu in list + */ + *head = this; + this->next = this->prev = this; + TRACELVL(5, (mcl_stdout, + "<- mcl_adu::insert_in_list: ok, inserted in empty list\n")) + return MCL_OK; + } + adul = (*head)->prev; + ASSERT(adul); + /* + * start from the highest seq number + */ + for (; this->seq < adul->seq; adul = adul->prev) { + if (adul == *head) { + /* we have cycled, so adu must be the first of list */ + *head = this; + this->next = adul; + this->prev = adul->prev; + adul->prev->next = this; + adul->prev = this; + TRACELVL(5, (mcl_stdout, + "<- mcl_adu::insert_in_list: ok, inserted at start of list\n")) + return MCL_OK; + } + } + ASSERT(this->seq != adul->seq); /* no duplicated adu for the present */ + this->next = adul->next; + adul->next->prev = this; + adul->next = this; + this->prev = adul; + TRACELVL(5, (mcl_stdout, "<- mcl_adu::insert_in_list:\n")) + return MCL_OK; +} + + +/** + * Remove an ADU from the adu list + */ +mcl_error_status +mcl_adu::remove_from_list(mcl_cb *const mclcb, + mcl_adu **head) +{ + mcl_adu *p, *n; // temp prev and next pointers + + ASSERT(head); + TRACELVL(5, (mcl_stdout, + "-> mcl_adu::remove_from_list: adu=x%x, seq=%d\n", + (int)this, this->seq)) + ASSERT(*head); + p = this->prev; + n = this->next; + if (p == this) { /* only one ADU in list */ + ASSERT(n == this); + *head = NULL; /* list is now empty */ + } else { + p->next = n; + n->prev = p; + if (*head == this) { + *head = n; /* adu was the first in list */ + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_adu::remove_from_list:\n")) + return MCL_OK; +} + + +/** + * Find an adu in a list with its sequence number. + * @param mclcb + * @param head pointer to the list head pointer + * @param seq ADU seq number + * @return returns a pointer to the adu if found, NULL otherwise + */ +mcl_adu * +mcl_adu::find_in_list (mcl_cb *const mclcb, + mcl_adu *head, + UINT32 aseq) +{ + mcl_adu *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_adu::find_in_list: seq=%d\n", aseq)) + if (!head) { + TRACELVL(5, (mcl_stdout, "<- mcl_adu::find_in_list: empty list\n")) + return NULL; + } +#if 0 + if (mclcb->findadu_cache && mclcb->findadu_cache->seq == aseq) { + TRACELVL(5, (mcl_stdout, "<- mcl_adu::find_in_list: found in cache\n")) + return mclcb->findadu_cache; + } +#endif + /* + * start from the highest seq number + */ + adu = head->prev; + while (1) { + ASSERT(adu); + if (adu->seq == aseq) { + /* found */ +#if 0 + mclcb->findadu_cache = adu; +#endif + TRACELVL(5, (mcl_stdout, "<- mcl_adu::find_in_list: found\n")) + return adu; + } + if (adu == head || adu->seq < aseq) { + /* we have cycled or new adu cannot be in list */ + TRACELVL(5, (mcl_stdout, "<- mcl_adu::find_in_list: new\n")) + return NULL; + } + adu = adu->prev; + } +} + + +/** + * Search a given block in this adu. + * @param + * @return returns a pointer to the block if found, NULL otherwise + */ +mcl_block * +mcl_adu::find_block (mcl_cb *const mclcb, + UINT32 bseq) +{ + mcl_block *list; /* in fact this is a tab, not a list! */ + + TRACELVL(5, (mcl_stdout, "-> mcl_adu::find_block: seq=%d\n", bseq)) + if (!(list = this->block_head)) { + TRACELVL(5, (mcl_stdout, + "<- mcl_adu::find_block: empty, return NULL\n")) + return NULL; + } + if (bseq > (UINT32)this->block_nb) { + TRACELVL(5, (mcl_stdout, + "<- mcl_adu::find_block: ERROR, out of bound\n")) + return NULL; + } else { + TRACELVL(5, (mcl_stdout, "<- mcl_adu::find_block: found\n")) + return (list + bseq); + } +} + + +/** + * Segment the ADU into blocks (ie. mcl_block) and packets (ie. mcl_du). + * Used only by the sender. + */ +mcl_error_status +mcl_adu::segment_for_tx (mcl_cb *const mclcb) +{ + mcl_block *blk; + mcl_du *du; + INT32 tot_blk_nb; /* total nb of blocks required */ + INT32 blk_seq; /* block seq number */ + INT32 tot_du_nb; /* total nb of DUs required */ + INT32 rem_du_nb; + INT32 nb; + INT32 i; + INT32 rem; + char *ptr; + INT32 max_k; /* max blk size in DU, depends on fec */ + + TRACELVL(5, (mcl_stdout, "-> mcl_adu::segment_for_tx:\n")) + max_k = mclcb->fec.get_k(); + /* + * segment the ADU... + * do it simply: allocate a tab of mcl_du and mcl_block objects + * rather than two linked lists! + */ + tot_du_nb = (int)ceil((double)this->get_len() / + (double)mclcb->get_payload_size()); + du = new mcl_du [tot_du_nb]; // no mcl_du default constructor + // for performance reasons! + if (du == NULL) + goto no_memory; + memset(du, 0, tot_du_nb * sizeof(mcl_du)); + + tot_blk_nb = (int)ceil((double)tot_du_nb / (double)max_k); + blk = new mcl_block [tot_blk_nb];// no mcl_block default constructor + // for performance reasons! + if (blk == NULL) + goto no_memory; + memset(blk, 0, tot_blk_nb * sizeof(mcl_block)); + + this->block_head = blk; + this->block_nb = tot_blk_nb; + + blk_seq = 0; + ptr = this->data; + rem = this->len; + for (rem_du_nb = tot_du_nb; rem_du_nb > 0; rem_du_nb -= nb) { + nb = min(rem_du_nb, max_k); + blk->adu = this; + blk->seq = blk_seq++; + blk->set_du_head(du); + blk->du_nb = nb; + blk->set_tx_status(BLK_TSTATUS_IN_PROGRESS); + /* blk->fec_du_head and fec_du_nb already set to NULL/0 */ + for (i = 0; i < nb; i++, du++) { + du->block = blk; + du->seq = i; + du->len = min(rem, mclcb->get_payload_size()); + du->data = ptr; + ptr += du->len; + rem -= du->len; + blk->len += du->len; /* last DU may be non full-sized */ + } + blk++; /* switch to next block */ + } + /* + * the full_size_block_len is the size of the first block, since + * if there is only one block this latter will not be full... + */ + this->full_size_block_len = this->block_head->len; + + ASSERT(rem == 0); + TRACELVL(1, (mcl_stdout, + "New ADU: seq=%d, len=%d, composed of %d blocks at most %d bytes/%d DUs long, total %d DUs, max payload_size=%d\n", + this->seq, this->len, this->block_nb, + this->full_size_block_len, this->block_head->du_nb, + tot_du_nb, mclcb->get_payload_size())) + TRACELVL(5, (mcl_stdout, "<- mcl_adu::segment_for_tx:\n")) + return MCL_OK; + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_adu::segment_for_tx: ERROR, no memory")) + mcl_exit(-1); + return MCL_ERROR; // unreachable +} + + diff --git a/src/norm/mcl_adu.h b/src/norm/mcl_adu.h new file mode 100644 index 0000000..d768664 --- /dev/null +++ b/src/norm/mcl_adu.h @@ -0,0 +1,445 @@ +/* $Id: mcl_adu.h,v 1.4 2004/02/18 07:56:18 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_ADU_H +#define MCL_ADU_H + +#include "mcl_norm_pkt_mgmt.h" // for mcl_data_hdr_infos_t definition + + +/** Initial Sequence number to use for the transmission of ADUs. */ +#define MCL_ISS 0 + +/** + * Possible ADU status at a sender. + * The possible transitions are the following: + * NIL -> IN_PROGRESS -> FINISH_TX -> DONE + */ +enum mcl_adu_tx_status { + ADU_TSTATUS_NIL = 0, /* void status */ + ADU_TSTATUS_IN_PROGRESS = 1, /* DUs are being transmitted */ + ADU_TSTATUS_FINISH_TX = 2, /* all DUs from all blocks have been + sent once, currently in repair mode*/ + ADU_TSTATUS_DONE = 3 /* totally and reliably sent, buffers + freed */ +}; + +/** + * Possible block status at a receiver. + * The possible transitions are the following: + * NIL -> IN_PROGRESS -> COMPLETED -> DECODED -> DELIVERED + */ +enum mcl_adu_rx_status { + ADU_STATUS_NIL = 0, /* void status */ + ADU_STATUS_IN_PROGRESS = 1, /* not yet ready */ + ADU_STATUS_COMPLETED = 2, /* received all DUs from all blocks */ + ADU_STATUS_DECODED = 3, /* COMPLETED and FEC decoding done */ + ADU_STATUS_DELIVERED = 4 /* sent to the receiving application */ +}; + + +/** + * Application Data Unit (ADU). + * They are the unit of data submitted by the sending application + * in an mcl_send[to] call. + * The ADU boundaries are preserved and communicated to the receivers. + * Both sender and receivers keep a linked list of ADUs. + */ +class mcl_adu { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor used by the sender. + * Initializes the various adu attributes, including its seq number. + * @param mclcb + * @param tx_or_rx is a sender calling this function or a receiver? + * @param alen length of this ADU + * @param saddr NULL at a sender when calling mcl_send, + * contains dest addr otherwise. + * Contains sender's addr at a receiver. + */ + mcl_adu (class mcl_cb *const mclcb, + //mcl_tx_or_rx tx_or_rx, + INT32 const alen, + mcl_addr const* saddr); + + /** + * Default constructor used by the receiver. + */ + mcl_adu (class mcl_cb *const mclcb, + mcl_data_hdr_infos_t const* dhdr_infos, + mcl_addr const* saddr); + /** + * Destructor + */ + ~mcl_adu (); + + /** + * Free all buffers allocated for this ADU. + * All the blocks are concerned, and this function also frees all + * the data and FEC DUs they contain. + * Used by sender and receiver. + */ + void remove_and_free_all_buffers (class mcl_cb *const mclcb); + + /** + * Returns the adu seq number. + */ + UINT32 get_seq (); + + /** + * Sets the ADU length in bytes. + * @param len length + */ + void set_len (INT32 len); + + /** + * Returns the ADU length in bytes. + * @return length + */ + INT32 get_len () const; + + /** + * Calculates and sets the padded length in bytes. + * @param len the real non padded length of this ADU in bytes + */ + void set_padded_len (const INT32 len); + + /** + * Returns the padded length in bytes. + * @return padded length in bytes + */ + INT32 get_padded_len () const; + + /** + * Set the destination or source address of this ADU. + */ + void set_addr (const struct sockaddr *const saddr, + const INT32 saddr_len); + //struct sockaddr *get_saddr (); + //INT32 get_saddr_len (); + + /** + * Set the data pointer. + * Only used by the sender. + * @param data_buf pointer to data buffer + */ + void set_data_ptr (char *const data_buf); + char *get_data_ptr (); + + /** + * True if the adu is for tx, false if it is for rx. + */ + bool is_a_tx_adu () const; + + /** + * Return the status of a transmitted adu. + */ + mcl_adu_tx_status get_tx_status () const; + + /** + * Set the new status of a transmitted adu. + */ + void set_tx_status (mcl_adu_tx_status new_status); + + /** + * Return the status of a received adu. + */ + mcl_adu_rx_status get_rx_status () const; + + /** + * Set the new status of a received adu. + */ + void set_rx_status (mcl_adu_rx_status new_status); + + /** + * Check if this adu is JUST completed and take appropriate measures. + * Used by a receiver when a new non-duplicated du is received for + * a block. + * @param mclcb + * @return true if completed and appropriate measures taken, + * false otherwise. + */ + bool check_if_completed_and_process (mcl_cb *const mclcb); + + /** + * Check if this adu is JUST completed and update state/stats. + * Used by a receiver when a new non-duplicated du is received for + * a block. + * @param mclcb + * @returns true if the adu has JUST been completely received + * (decoded or not), false otherwise. + */ + bool check_if_just_completed (mcl_cb *const mclcb); + + /** + * Check if this adu is completed. + * Used by a receiver. + * @param mclcb + * @returns true if the adu has been completely received + * (decoded or not). + */ + bool check_if_completed (mcl_cb *const mclcb); + + /** + * Decode all the block of an ADU. + * @param mclcb + * @returns + */ + mcl_error_status decode_all_blocks (mcl_cb *const mclcb); + + /** + * Return the head of the block list for this adu. + * This info is read-only (initialized at adu creation). + */ + class mcl_block *get_block_head () const; + + /** + * Return the number of blocks for this adu. + * This info is read-only (initialized at adu creation). + */ + INT32 get_block_nb () const; + + /** + * Search a given block in this adu. + * @param mclcb + * @param bseq block sequence number + * @return returns a pointer to the block if found, NULL otherwise + */ + class mcl_block *find_block (mcl_cb *const mclcb, + UINT32 seq); + + /** + * Return the length in bytes of a full-sized block. + */ + INT32 get_full_size_block_len () const; + + /** + * Segment an adu. + * Essentially required by small block FEC codes. + * Only used by the sender. + * @param mclcb + * @return + */ + mcl_error_status segment_for_tx (mcl_cb *const mclcb); + + /** + * Get adu before this one in list. + * @return Returns the prev pointer value as it is... + */ + mcl_adu *get_prev () const; + + /** + * Get adu after this one in list. + * @return Returns the next pointer value as it is... + */ + mcl_adu *get_next () const; + + /** + * Insert an adu in a list. + * Called by mcl_tx::insert_adu and mcl_rx::insert_adu methods with + * the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ + mcl_error_status insert_in_list (mcl_cb *const mclcb, + mcl_adu **head); + + /** + * Remove an adu from a list. + * Called by mcl_tx::remove_adu and mcl_rx::remove_adu methods with + * the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ + mcl_error_status remove_from_list (mcl_cb *const mclcb, + mcl_adu **head); + + /** + * Find an adu in a list with its sequence number. + * @param mclcb + * @param head pointer to the list head pointer + * @param aseq ADU seq number + * @return returns a pointer to the adu if found, NULL otherwise + */ + mcl_adu *find_in_list (mcl_cb *const mclcb, + mcl_adu *head, + UINT32 aseq); + + + + /****** Public Attributes *********************************************/ + mcl_addr addr; // ADU recvd from or destinated to + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + mcl_adu *prev, *next; + mcl_tx_or_rx type; // differentiate between TX and RX ADU + UINT32 seq; // seq nb of this ADU + INT32 len; // number of bytes in this ADU + INT32 padded_len; // len with optional 0 padding + INT32 full_size_block_len; // lenght in bytes of a full size + // block if any, else size of 1st blk + class mcl_block *block_head; // first block of this ADU in list + INT32 block_nb; // number of blocks in this ADU + /* fields only used by the sender */ + char *data; // ptr to data buffer */ + mcl_adu_tx_status tx_status; // ADU tx status + /* fields only used by the receivers */ + mcl_adu_rx_status rx_status; // ADU rx status + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline UINT32 +mcl_adu::get_seq () +{ + return this->seq; +} + +inline void +mcl_adu::set_len (INT32 len) +{ + this->len = len; +} + +inline INT32 +mcl_adu::get_len () const +{ + return this->len; +} + + +inline INT32 +mcl_adu::get_padded_len () const +{ + return this->padded_len; +} + + +inline void +mcl_adu::set_addr (const struct sockaddr *const saddr, const INT32 saddr_len) +{ + this->addr.set_addr_struct((struct sockaddr_in*)saddr); +} + + +#if 0 +inline struct sockaddr * +mcl_adu::get_saddr () +{ + return &(this->saddr); +} + +inline INT32 +mcl_adu::get_saddr_len () +{ + return this->saddr_len; +} +#endif + +inline void +mcl_adu::set_data_ptr (char *const data_buf) +{ + ASSERT(this->type == MCL_TX); + this->data = data_buf; +} + +inline char * +mcl_adu::get_data_ptr () +{ + return this->data; +} + +inline bool +mcl_adu::is_a_tx_adu () const +{ + return (this->type == MCL_TX ? true : false); +} + +inline mcl_adu_tx_status +mcl_adu::get_tx_status () const +{ + return this->tx_status; +} + +inline void +mcl_adu::set_tx_status (mcl_adu_tx_status new_status) +{ + this->tx_status = new_status; +} + +inline mcl_adu_rx_status +mcl_adu::get_rx_status () const +{ + return this->rx_status; +} + +inline void +mcl_adu::set_rx_status (mcl_adu_rx_status new_status) +{ + this->rx_status = new_status; +} + +inline bool +mcl_adu::check_if_completed (mcl_cb *const mclcb) +{ + return ((this->rx_status >= ADU_STATUS_COMPLETED) ? true : false); +} + +inline mcl_block * +mcl_adu::get_block_head () const +{ + return this->block_head; +} + +inline INT32 +mcl_adu::get_block_nb () const +{ + return this->block_nb; +} + +inline INT32 +mcl_adu::get_full_size_block_len () const +{ + return this->full_size_block_len; +} + +inline mcl_adu * +mcl_adu::get_prev () const +{ + return this->prev; +} + +inline mcl_adu * +mcl_adu::get_next () const +{ + return this->next; +} + +#endif // !MCL_ADU_H + diff --git a/src/norm/mcl_async_fec.cpp b/src/norm/mcl_async_fec.cpp new file mode 100644 index 0000000..a55706b --- /dev/null +++ b/src/norm/mcl_async_fec.cpp @@ -0,0 +1,880 @@ +/* $Id: mcl_async_fec.cpp,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/****** Following two classes are private and only used by mcl_fec.cpp ******/ + +/* + * FEC job class. + */ +mcl_fec_job::mcl_fec_job (mcl_block *blk, + INT32 start_index, + INT32 fec_nb) +{ + this->next = NULL; + this->block = blk; + this->first_fec_index = start_index; + this->fec_desired = fec_nb; +} + + +mcl_fec_job::~mcl_fec_job () +{ +} + + +/* + * Class that provides a FEC job list. + */ +mcl_fec_job_list::mcl_fec_job_list () +{ + this->head = NULL; + this->tail = NULL; + mcl_init_lock (&(this->list_lock)); +} + +mcl_fec_job_list::~mcl_fec_job_list () +{ +} + + +/* + * insert in tail + */ +void +mcl_fec_job_list::enqueue (mcl_fec_job *job) +{ + this->lock(); + ASSERT(job->next == NULL); + if (this->tail) { + this->tail->next = job; + } else { + ASSERT(this->head == NULL); + this->head = job; + } + this->tail = job; + this->unlock(); +} + + +/* + * remove from head + */ +mcl_fec_job * +mcl_fec_job_list::dequeue (void) +{ + mcl_fec_job *job; + + this->lock(); + if (this->head) { + job = this->head; + this->head = job->next; + if (this->tail == job) { + this->tail = NULL; + ASSERT(this->head == NULL); + } + } else { + ASSERT(this->tail == NULL); + job = NULL; + } + this->unlock(); + return job; +} + + +/****** Private FEC encoding thread class *************************************/ + +mcl_fec_thread::mcl_fec_thread () +{ + this->fec_thread_id = 0; +} + + +mcl_fec_thread::~mcl_fec_thread () +{ + this->fec_thread_id = 0; +} + + +void +mcl_fec_thread::start (mcl_cb *const mclcb) +{ + /* + * create the fec thread... + */ +#ifdef WIN32 + if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mcl_fec_thread::fec_thread, + NULL, 0, (LPDWORD)mclcb) == NULL) { + perror("mcl_fec_thread::start: CreateThread"); + mcl_exit(1); + } +#else + if (pthread_create((pthread_t*)&(this->fec_thread_id), + NULL, + mcl_fec_thread::fec_thread, + (void*)mclcb) != 0) { + perror("mcl_fec_thread::start: pthread_create"); + mcl_exit(1); + } +#endif +} + + +#if 0 +/** + * Stops the FEC encoding service. + */ +void +mcl_fec_thread::stop (mcl_cb *const mclcb) +{ +#ifndef WIN32 + if (this->fec_thread_id != 0) { + pthread_cancel(this->fec_thread_id); + pthread_join(this->fec_thread_id, NULL); + } +#endif +} +#endif + + +/** + * FEC encoding thread. + * Retrieve a job from the job list, perform FEC encoding, and put encoded + * packets on the transmission waiting queue + */ +void * +mcl_fec_thread::fec_thread (void *arg) +{ + mcl_cb *mclcb = (mcl_cb*)arg; + mcl_fec_job *job; + mcl_block *blk; + mcl_du *du; + INT32 i; + INT32 fec_created; + + TRACELVL(5, (mcl_stdout, "-> mcl_fec_thread::fec_thread:\n")) +#ifndef WIN32 + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + /* + * cancellation is deferred till next check point , i.e. points + * in code where we know everything is in a stable state + */ + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + while (1) { +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + while ((job = mclcb->fec.fec_job_list.dequeue()) == NULL) { + mcl_usleep(DFLT_POLLING_PERIOD); +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + + } + /* + * got a new job, now create the desired fec... + */ + blk = job->block; + TRACELVL(5, (mcl_stdout, + " mcl_fec_thread::fec_thread: create %d fec for blk %d/%d\n", + job->fec_desired, blk->adu->get_seq(), blk->seq)) + /* + * Produce FEC packets. + * XXX: a bit dangerous... + * Block object modified without being locked for this mclcb! + * This is required though to enable an asynchronous fec + * encoding... + * There is a risk if the session is destroyed in the meantime, + * or the adu free'ed... + */ + fec_created = mclcb->fec.fec_encoding_func(mclcb, blk, + job->first_fec_index, + job->fec_desired); +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + /* + * and now get the session lock... + */ + mclcb->lock(); + /* + * no longer pending. + * NB: decrement by fec_desired and not fec_created since + * no additional fec will be created for this job, even + * if fec_created < fec_desired... + */ + mclcb->fec.decr_pending_fec_creation_req(blk, job->fec_desired); + //if (blk->get_fec_du_nb_in_list() < job->fec_desired) + if (fec_created < job->fec_desired) { + /* failed, the encoder didn't produce the desired FEC */ + PRINT_ERR((mcl_stderr, + "mcl_fec_thread::fec_thread: ERROR, mcl_fec_encode failed: wanted %d, got %d\n", + job->fec_desired, fec_created)) +#ifdef DEBUG + mcl_exit(-1); +#endif + } + /* + * register each FEC packet created in the tx window. + * Must be done starting by the end of FEC list as FEC DUs + * may have already been produced. + */ + for (du = blk->get_fec_du_tail(), i = fec_created; + i > 0; i--, du = du->get_prev()) { + ASSERT(du); + mclcb->tx_window.register_new_du(mclcb, du); + } + mclcb->unlock(); +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + delete job; + } + TRACELVL(5, (mcl_stdout, "<- mcl_fec_thread::fec_thread:\n")) +} + + +/****** And this is the public class ******************************************/ + + +#if 0 +mcl_fec::mcl_fec () +{ + this->initialized = false; +#ifdef RSE_FEC + this->max_k = this->max_n = GF_SIZE; +#else + // no fec codec used, so use default conservative values... + this->max_k = this->max_n = 255; +#endif + this->cur_n = this->max_n; + this->cur_k = this->max_n >> 1; // default: half data, half fec +} + + +mcl_fec::~mcl_fec () +{ +} +#endif + + +mcl_fec::mcl_fec () +{ + /* set everything to 0 */ + memset(this->max_k, 0, sizeof(this->max_k)); + memset(this->max_n, 0, sizeof(this->max_n)); + memset(this->cur_k, 0, sizeof(this->cur_k)); + memset(this->cur_n, 0, sizeof(this->cur_n)); + /* + * initialize the fec class for each supported FEC code. + * the order is significant since the last call specifies the + * default FEC code. + */ + this->initialize(MCL_FEC_CODE_NULL); +#ifdef RSE_FEC + this->initialize(MCL_FEC_CODE_RSE); +#endif + +} + + +mcl_fec::~mcl_fec () +{ +#ifdef DEBUG + memset(this->max_k, 0, sizeof(this->max_k)); + memset(this->max_n, 0, sizeof(this->max_n)); + memset(this->cur_k, 0, sizeof(this->cur_k)); + memset(this->cur_n, 0, sizeof(this->cur_n)); +#endif +} + + +/** + * Initializes the FEC class for a given FEC code. + * => See header file for more informations. + */ +void +mcl_fec::initialize (const INT32 new_code) +{ + switch (new_code) { +#ifdef RSE_FEC + case MCL_FEC_CODE_RSE: + this->fec_codec = MCL_FEC_CODE_RSE; + ASSERT(RSE_MAX_K <= RSE_MAX_N); + ASSERT(RSE_MAX_N <= GF_SIZE); + this->max_k[MCL_FEC_CODE_RSE] = RSE_MAX_K; + this->max_n[MCL_FEC_CODE_RSE] = RSE_MAX_N; + this->cur_k[MCL_FEC_CODE_RSE] = RSE_MAX_K; + this->cur_n[MCL_FEC_CODE_RSE] = min(2 * RSE_MAX_K, RSE_MAX_N); + // default: half data, half fec + break; +#endif + case MCL_FEC_CODE_NULL: + // no fec codec used, so use default conservative values... + this->fec_codec = MCL_FEC_CODE_NULL; + this->max_k[MCL_FEC_CODE_NULL] = 255; + this->max_n[MCL_FEC_CODE_NULL] = 255; + this->cur_k[MCL_FEC_CODE_NULL] = 255; + this->cur_n[MCL_FEC_CODE_NULL] = 255; + break; + default: + PRINT_ERR((mcl_stderr, + "mcl_fec::initialize: ERROR, called with unsupported FEC code %d\n", + new_code)) + mcl_exit(-1); + } + this->max_fratio = this->cur_n[new_code] / this->cur_k[new_code]; + /* + * check it is coherent with the MAX_FEC_RATIO constant + * defined in mcl_profile.h + */ + if (this->max_fratio > MAX_FEC_RATIO) { + PRINT_ERR((mcl_stderr, + "mcl_fec::initialize: ERROR, the calculated max_fratio(%f) is larger than MAX_FEC_RATIO (%f) for code %d\nCheck and correct the various settings in mcl_profile.h accordingly...\n", + this->max_fratio, MAX_FEC_RATIO, new_code)) + mcl_exit(-1); + } +} + + +/** + * Set the FEC code to be used. + * This function is sender specific (a receiver gets the FEC + * codec information info from the various incoming packet fields). + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::set_fec_code (mcl_cb *const mclcb, + const INT32 new_code) +{ + if (new_code == MCL_FEC_CODE_NULL) { + this->fec_codec = MCL_FEC_CODE_NULL; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use NO FEC\n")) + return MCL_OK; + } +#ifdef RSE_FEC + else if (new_code == MCL_FEC_CODE_RSE) { + this->fec_codec = MCL_FEC_CODE_RSE; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use RSE\n")) + return MCL_OK; + } +#endif + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_code: ERROR, code %d unknown\n", new_code)) + return MCL_ERROR; +} + + +#if 0 +/** + * Stop the encoding thread. + */ +void +mcl_fec::stop () +{ + if (this->initialized == true) { + // delete the thread + this->fec_encoding_thread.stop(mclcb); + this->initialized = false; + } // else nothing to do, thread not created. + return MCL_OK; + +} +#endif + +#if 0 +/** + * Set the maximum FEC ratio, defined as n/k. + * Calling this function modifies the cur_k/max_k accordingly. + * @return Completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_fec::set_max_fec_ratio (mcl_cb *const mclcb, + float max_fec_ratio) +{ + INT32 tmp_max_k; + INT32 tmp_cur_k; + + if (max_fec_ratio < 1.0 || max_fec_ratio > 10.0) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_max_fec_ratio: ERROR, bad max_fec_ratio; got %f, should be in [1.0; 10.0]\n", max_fec_ratio)) + goto bad; + } + tmp_max_k = (INT32)(this->max_n / max_fec_ratio); + tmp_cur_k = (INT32)(this->cur_n / max_fec_ratio); + if (tmp_max_k < 1 || tmp_cur_k < 1) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_max_fec_ratio: ERROR, max_fec_ratio %f too large\n", max_fec_ratio)) + goto bad; + } + this->max_k = tmp_max_k; + this->cur_k = tmp_cur_k; + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::set_max_fec_ratio: max_k/n=(%d; %d), cur_k/n=(%d; %d)\n", + this->max_k, this->max_n, this->cur_k, this->cur_n)) + return MCL_OK; + +bad: + PRINT_ERR((mcl_stderr, + "mcl_fec::set_max_fec_ratio: ERROR, bad max_fec_ratio; got %f, should be in [1.0; 10.0]\n", max_fec_ratio)) + return MCL_ERROR; +} +#endif + +/** + * Set the maximum FEC ratio, defined as n/k. + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::set_max_fec_ratio (mcl_cb *const mclcb, + float max_fec_ratio) +{ + INT32 tmp_max_k; + INT32 tmp_cur_k; + + if (max_fec_ratio < 1.0 || max_fec_ratio > 10.0) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_max_fec_ratio: ERROR, bad max_fec_ratio; got %f, should be in [1.0; 10.0]\n", max_fec_ratio)) + goto bad; + } + tmp_max_k = (INT32)(this->get_max_n() / max_fec_ratio); + tmp_cur_k = (INT32)(this->get_n() / max_fec_ratio); + if (tmp_max_k < 1 || tmp_cur_k < 1) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_max_fec_ratio: ERROR, max_fec_ratio %f too large\n", max_fec_ratio)) + goto bad; + } + this->max_k[this->fec_codec] = tmp_max_k; + this->set_k(tmp_cur_k); + this->max_fratio = max_fec_ratio; + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::set_max_fec_ratio: max_k/n=(%d; %d), cur_k/n=(%d; %d)\n", + this->get_max_k(), this->get_max_n(), + this->get_k(), this->get_n())) + return MCL_OK; + +bad: + PRINT_ERR((mcl_stderr, + "mcl_fec::set_max_fec_ratio: ERROR, bad max_fec_ratio; got %f, should be in [1.0; 10.0]\n", max_fec_ratio)) + return MCL_ERROR; +} + + + +/** + * Return the number of available FEC packets (ie that have been + * created) that have not yet been sent. + */ +INT32 +mcl_fec::get_nb_fresh_fec_pkts (mcl_cb *const mclcb, + mcl_block *blk) +{ + return 0; // TODO, in the meantime assume everything has been sent +} + + +/** + * Return the number of FEC packets that can still be created for this + * block. + * Does NOT take into account the number of pending FEC creation requests. + */ +INT32 +mcl_fec::get_rem_nb_fec_pkts_to_create (mcl_cb *const mclcb, + mcl_block *blk) +{ + return (this->get_n() - blk->du_nb - blk->get_fec_du_nb_in_list()); +} + + +/** + * Encode the block and create the requested number of new FEC packets. + * Encoding is done asynchronously by the fec_thread + * and the results inserted automatically in the sender's + * transmission queue and in the block's FEC du list. + * @return < 0 if error, the number of FEC symbols created if ok + */ +INT32 +mcl_fec::encode (mcl_cb *const mclcb, + mcl_block *blk, + INT32 fec_desired) +{ + INT32 k; // effective k for this block + INT32 max_fec; // max nb of fec for this blk + mcl_fec_job *job; + INT32 start_index; // index of 1st FEC pkt to create + INT32 fec_to_create; + + TRACELVL(5, (mcl_stdout, + "-> mcl_fec::encode: blk seq=%d, want %d fec\n", + blk->seq, fec_desired)) + if (this->initialized == false) { + this->fec_encoding_thread.start(mclcb); + this->initialized = true; + } + /* + * Sanity checks... + */ + k = blk->du_nb; + ASSERT(k <= this->get_k()); + max_fec = get_rem_nb_fec_pkts_to_create(mclcb, blk); + if (fec_desired > max_fec || fec_desired <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_fec::encode: ERROR, illegal nb of FEC symbols desired (got %d, should be in ]0; %d]\n", + fec_desired, max_fec)) + return (-1); + } + /* do not consider the nb of pending fec creation requests */ + start_index = k + blk->get_fec_du_nb_in_list() + + this->get_pending_fec_creation_req(blk); + fec_to_create = fec_desired - this->get_pending_fec_creation_req(blk); + if (fec_to_create <= 0) { + TRACELVL(5, (mcl_stdout, "<- mcl_fec::encode: not required, enough pending FEC creations\n")) + return(0); + } + /* + * create a job and insert it in the fec_job list + */ + job = new mcl_fec_job(blk, start_index, fec_to_create); + this->fec_job_list.enqueue(job); + this->incr_pending_fec_creation_req(blk, fec_to_create); /* recorded */ + TRACELVL(5, (mcl_stdout, "<- mcl_fec::encode:\n")) + return fec_desired; +} + + +/** + * Performs FEC encoding for this block. + * This function may be called several times for the same block (even + * if calling it once may be faster), for instance to satisfy additional + * retransmission requests. + * @param blk block for which FEC packets must be created + * @param start_index index of the first (inclusive) FEC packet to create + * @param fec_desired number of FEC packets that must be created from + * start_index + * @returns number of FEC packets created if ok, < 0 if error. + */ +INT32 +mcl_fec::fec_encoding_func (mcl_cb *mclcb, + mcl_block *blk, + INT32 start_index, + INT32 fec_desired) +{ + INT32 k; /* k source DUs... */ + /* FEC DU seq nbs follow source DUs */ + INT32 n; /* total of n FEC+source DUs */ + UINT32 du_len; + UINT32 last_du_len; + INT32 i; + void *code; + mcl_du *fec_du; + char *fec_data; + char **src; + mcl_du *du; + + ASSERT(blk); + TRACELVL(5, (mcl_stdout, + "-> mcl_fec::fec_encoding_func: blk=%d, want %d fec\n", + blk->seq, fec_desired)) + k = blk->du_nb; + ASSERT(start_index >= k); + ASSERT(fec_desired > 0); + /* + * compute the size of a full-sized DU and of the last DU + * which may be shorter + */ + du_len = mclcb->get_payload_size(); + last_du_len = (k > 1) ? blk->len % du_len : blk->len; + if (last_du_len == 0) + last_du_len = du_len; /* multiple */ + /* + * create all the required FEC DUs for this block + */ + n = start_index + fec_desired; + ASSERT(n <= this->get_n()); + + if (!(code = fec_new(k,n))) { + goto no_memory; + } + /* + * no data copy except for the last du which may be shorter + */ + if (!(src = (char**)malloc(sizeof(char*) * n))) { + goto no_memory; + } + for (i = 0, du = blk->get_du_head(); i < k - 1; i++, du++) { + src[i] = (char*)(du->data); + } + if (!(src[k-1] = (char*)calloc(1, du_len))) { + goto no_memory; + } + ASSERT(du->seq == (UINT32)k-1); + ASSERT(du->len == last_du_len); + /* + * now create the n-k FEC DUs + */ + memcpy(src[k-1], du->data, last_du_len); + for (i = start_index; i < n; i++) { + if (!(fec_data = (char *) malloc(du_len))) { + goto no_memory; + } + fec_encode(code, (void**) src, fec_data, i, du_len); + fec_du = new mcl_du; + fec_du->block = blk; + fec_du->data = fec_data; + fec_du->seq = i; + fec_du->len = du_len; + fec_du->is_fec = true; + fec_du->pkt = NULL; // this is how a tx DU is distinguished + // from a rx DU! + fec_du->set_next(NULL); + fec_du->set_prev(NULL); + /* + * Use a linked list of FEC DUs rather than a single tab as + * with data DUs on the sending side! + */ + if (blk->insert_in_fec_du_list(mclcb, fec_du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_fec::fec_encoding_func: ERROR, insert_in_fec_du_list() failed\n")) +//#if 0 +printf("insert failed for fec_du seq=%d; start_idx=%d, fec_desired=%d\n", fec_du->seq, start_index, fec_desired); +int ii; +mcl_du *fdu; +for (ii=0, fdu = blk->get_fec_du_head(); iiget_fec_du_nb_in_list(); ii++, fdu = fdu->get_next()){ + printf("fec_du: seq=%d\n", fdu->seq); +} +//#endif + mcl_exit(-1); + } + TRACELVL(5, (mcl_stdout, + " mcl_fec::fec_encoding_func: created FEC seq=%d, len=%d, buf=x%x\n", + (INT32)fec_du->seq, (INT32)fec_du->len, + (INT32)fec_du->data)) + } + free(src[k-1]); + free(src); + fec_free(code); + TRACELVL(5, (mcl_stdout, "<- mcl_fec::fec_encoding_func: %d fec_du\n", + n - start_index)) + return (n - start_index); + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_fec::fec_encoding_func: ERROR, no memory\n")) + mcl_exit(-1); + return -1; // useless but avoids a warning +} + + +INT32 +mcl_fec::decode (mcl_cb *const mclcb, + mcl_block *blk) +{ + INT32 k; + INT32 n; + UINT32 du_len; /* full-sized DU length */ + UINT32 last_du_len; /* last DU (true) length */ + INT32 i; + u_char **dst; /* put rx data or fec here... */ + INT32 rx_index[GF_SIZE]; /* ... and their seq# here */ + UINT32 rem; /* remaining nb of DUs */ + void *code; + mcl_du *du; + UINT32 seq; /* next seq number expected */ +#ifdef DEBUG + char *data; /* data buffer */ +#endif + mcl_rx_pkt *pkt; /* used for data DUs created during decoding */ + u_char *buf; /* buffer where data/FEC DU data is copied */ + INT32 off; /* offset */ + + + ASSERT(blk); + TRACELVL(5, (mcl_stdout, "-> mcl_fec::decode: block seq=%d\n", blk->seq)) + /* + * check that FEC decode is indeed needed (i.e. that + * we need at least one FEC DU) + */ + k = blk->du_nb; + if (blk->get_du_nb_in_list() >= k) { + blk->set_rx_status(BLK_STATUS_DECODED); + TRACELVL(5, (mcl_stdout, + " mcl_fec::decode: decoding not needed\n")) + /*TRACELVL(5, ("decode: k=%d, du_in_list=%d, fec_in_list=%d\n", k, blk->get_du_nb_in_list(), blk->get_fec_du_nb_in_list()))*/ + goto free_fec_du; + } + /* + * compute the size of a full-sized DU and of the last DU + * which may be shorter + */ + du_len = mclcb->get_payload_size(); + last_du_len = (k > 1) ? blk->len % du_len : blk->len; + if (last_du_len == 0) + last_du_len = du_len; /* multiple */ + /* + * copy data and fec in dst buffer array first + * NB: this is required by the current FEC codec which modifies + * the dst buffers!!! + */ + if (!(dst = (u_char **) malloc(k * sizeof(u_char *)))) { + goto no_memory; + } + /* alloc a single large buf, where to copy all data/FEC DU data... */ + if (!(buf = (u_char *) malloc(k * du_len))) { + goto no_memory; + } + /* and remember the location of each DU buffer */ + for (i = 0, off = 0; i < k; i++, off += du_len) { + dst[i] = buf + off; + } + i = 0; /* index in rx_index[] */ + /* + * copy data DU to the dst array first + */ + for (rem = blk->get_du_nb_in_list(), du = blk->get_du_head(); + rem > 0; i++, rem--) { + ASSERT(du); + /* WARNING: if the following test failed, you probably forgot */ + /* to set the same tx_profile at the source AND receiver */ + if (du->len != du_len && du->len != last_du_len) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR: bad packet len (expected %d or %d, got %d)\nCheck transmission profiles at sender/receiver\n", + du_len, last_du_len, du->len)) + goto fatal_error; + } + if (i >= k) + break; /* security, eg. if there are more than k DUs */ + memcpy(dst[i], du->data, du->len); + if (du->len < du_len) { + /* non full-sized DU, so reset the remaining bytes */ + memset(dst[i] + du->len, 0, du_len - du->len); + } + rx_index[i] = du->seq; +#if 0 + PRINT_OUT((mcl_stdout, "decode: copy DATA du->seq=%d in dst[%d], rx_index[%d]=%d\n", + du->seq, i, i, rx_index[i])) +#endif + du = du->get_next(); + } + /* + * copy FEC DUs to the dst array now + */ + for (rem = blk->get_fec_du_nb_in_list(), du = blk->get_fec_du_head(); + rem > 0; i++, rem--, du = du->get_next()) { + ASSERT(du); + ASSERT(du->len == du_len); + if (i >= k) { + /* security, if there are more than k data+FEC DUs */ + break; + } + memcpy(dst[i], du->data, du->len); + /* rx_index[i] = du->seq + k; */ + rx_index[i] = du->seq; +#if 0 + PRINT_OUT((mcl_stdout, "decode: copy FEC du->seq=%d in dst[%d], rx_index[%d]=%d\n", + du->seq, i, i, rx_index[i])) +#endif + } + /* + * now decode + * NB: all the dst packets must be du_len long + */ + n = this->get_n(); + code = fec_new(k, n); + if (fec_decode(code, (void**)dst, rx_index, du_len)) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR, fec_decode failed\n")) + return -1; + } + fec_free(code); + + /* + * now update the block with the rx or reconstructed DUs + */ + for (rem = blk->du_nb, seq = 0, du = blk->get_du_head(); + rem > 0; rem--, seq++, du = du->get_next()) { + if (du && du->seq == seq) { + /* nothing to do, DU already received */ + continue; + } + /* + * else copy it from the FEC decoded matrix + */ + du = new mcl_du; + + du->block = blk; + du->seq = seq; + if (rem > 1) + du->len = du_len; + else + du->len = last_du_len; + du->is_fec = false; + du->set_next(NULL); + du->set_prev(NULL); + /* + * copy/store data now + */ + pkt = new mcl_rx_pkt (du->len); + pkt->pkt_len = du->len; + du->pkt = pkt; + du->data = pkt->get_buf(); + memcpy(du->data, dst[seq], du->len); + /* + * and insert it in the data DU list + */ + if (blk->insert_in_du_list(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR, insert_in_fec_du_list() failed\n")) + mcl_exit(-1); + } + TRACELVL(5, (mcl_stdout, + " decode: created DU seq=%d from dst[%d], len=%d, data buffer=x%x, du->data=x%x\n", + du->seq, seq, du->len, (int)data, (int)du->data)) +#if 0 + DumpBuffer(data, sizeof(char*) + du->len, (sizeof(char*) + du->len)>>2); +#endif + } + blk->set_rx_status(BLK_STATUS_DECODED); + + /* + * free the dst[] array and fec DU list now + */ + /* + * Warning: the fec_decode function can shuffle dst[] entries, so + * the new dst[0] entry may not point to buffer allocated previously! + */ + free(buf); + free(dst); +free_fec_du: + blk->remove_and_free_all_fec_dus(mclcb); + + TRACELVL(5, (mcl_stdout, "<- mcl_fec::decode: ok\n")) + return 0; + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR, no memory")) + mcl_exit(-1); + +fatal_error: + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR")) + mcl_exit(-1); + return -1; /* unreachable; avoid a compiler warning */ +} + diff --git a/src/norm/mcl_async_fec.h b/src/norm/mcl_async_fec.h new file mode 100644 index 0000000..5b96624 --- /dev/null +++ b/src/norm/mcl_async_fec.h @@ -0,0 +1,460 @@ +/* $Id: mcl_async_fec.h,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_FEC_H +#define MCL_FEC_H + + +/****** Two private classes only used by mcl_fec.cpp (private members) ********/ + + +/** + * FEC job class. + * Used by the sender to ask for FEC encoding of a given block. + * This job is enqueued on the FEC job list and encoding will be performed + * by the FEC encoding thread. + */ +class mcl_fec_job { + +public: + /****** Public Members ************************************************/ + mcl_fec_job (mcl_block *blk, + INT32 start_index, + INT32 fec_nb); + + ~mcl_fec_job (); + + /****** Public Attributes *********************************************/ + mcl_fec_job *next; + mcl_block *block; // block to encode + INT32 first_fec_index;// index of first FEC symbol to create + INT32 fec_desired; // number of FEC symbols to produce + +private: + +}; + + +/** + * Class that provides a FEC job list. + * There is one FEC job list per session. + */ +class mcl_fec_job_list { + +public: + /****** Public Members ************************************************/ + mcl_fec_job_list (); + ~mcl_fec_job_list (); + + /** + * Enqueue a FEC job. + * @param job FEC job + */ + void enqueue (mcl_fec_job *job); + /** + * Dequeue a FEC job. + * @return FEC job if there is one, NULL if nothing to do + */ + mcl_fec_job *dequeue (void); + +private: + /****** Private Members ***********************************************/ + /** Get the list lock. */ + void lock (void); + + /** Release the list lock. */ + void unlock (void); + + /****** Private Attributes ********************************************/ + /** linked list of FEC jobs. */ + mcl_fec_job *head; + mcl_fec_job *tail; + + /** FEC job list lock. */ + mcl_mutex_t list_lock; +}; + + +/****** Private FEC encoding thread class (private member) ********************/ + + +/** + * FEC encoding thread for a given MCL session. + */ +class mcl_fec_thread { +public: + /****** Public Members ************************************************/ + mcl_fec_thread (); + ~mcl_fec_thread (); + + /** + * Starts the FEC encoding service. + * Exits in case of error. + */ + void start (mcl_cb *const mclcb); + + /** + * Return the thread id. + * Required to enable a safe thread destruction. + */ + mcl_thread_t get_fec_thread_id (); + + /****** Public Attributes *********************************************/ + +private: + /****** Private Members ***********************************************/ + + /** + * Thread dedicated to FEC encoding. + * This thread retrieves encoding jobs from the fec_job_list, + * performs encoding by calling the fec_encoding_func, and + * enqueues FEC packets produced in the tx_window. + * Needs to be static since pthread_create() cannot be used with + * non-static member functions. + * @param arg mclcb session pointer + */ + static void *fec_thread (void *arg); + + /****** Private Attributes ********************************************/ + + /** Idf of the FEC encoding thread. */ + mcl_thread_t fec_thread_id; + +}; + + +/****** This is the public class **********************************************/ + + +/** + * Main FEC class. + */ +class mcl_fec { +friend class mcl_fec_thread; // required for fec_thread to access + // fec_encoding_func() and fec_job_list + +public: + /****** Public Members ************************************************/ + mcl_fec (); + ~mcl_fec (); + + /** + * Initializes the FEC class for a given FEC code. + * Replaces the default constructor. + * @param new_code FEC code to use. Can be one of + * MCL_FEC_CODE_NULL, ...RSE, ...LDGM, ...LDPC. + * (see mcl_lib_api_alc.h). Default is NULL. + */ + void initialize (const INT32 new_code = 0); + + /** + * Return the maximum block size (in number of DUs). + * This parameter is set at mcl_fec service initialization + * depending on the FEC code used. + * We have: max_k <= max_n (no FEC DU if equal). + */ + INT32 get_max_k () const; + + /** + * Return the maximum block size (in number of DUs). + * This parameter is set at mcl_fec service initialization + * depending on the FEC code used. + */ + INT32 get_max_n () const; + + /** + * Set the effective block size to use (in number of DUs). + * 0 < k <= max_k made possible by the code. + * If k == n, then no FEC DU will be produced. + */ + void set_k (const INT32 k); + + /** + * Return the effective block size used currently (in number of DUs). + */ + INT32 get_k (void) const; + + /** + * Set the effective n to use (in number of DUs). + * 0 < n <= max_n made possible by the code. + * If k == n, then no FEC DU will be produced. + */ + void set_n (const INT32 n); + + /** + * Return the effective n parameter used currently (in number of DUs). + */ + INT32 get_n (void) const; + + /** + * Set the FEC code to be used. + * This function is sender specific (a receiver gets the FEC + * codec information info from the various incoming packet fields). + * This function only changes the FEC code to use from now on, + * without modifying anything else. It assumes that the FEC + * codec specific parameters have already been initialized. + * @param new_code FEC code to use from now on... + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_fec_code (class mcl_cb *const mclcb, + const INT32 new_code); + + /** + * Set the maximum FEC ratio, defined as n/k. + * Calling this function modifies the cur_k/max_k accordingly. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_max_fec_ratio (mcl_cb *const mclcb, + float max_fec_ratio); + + /** + * Return the maximum FEC ratio, defined as n/k. + */ + float get_max_fec_ratio () const; + + /** + * Return the number of available FEC packets (ie that have been + * created) that have not yet been sent. + */ + INT32 get_nb_fresh_fec_pkts (mcl_cb *const mclcb, + mcl_block *blk); + + /** + * Return the number of FEC packets that can still be created for this + * block. + * Does NOT take into account the number of pending FEC creation + * requests. + */ + INT32 get_rem_nb_fec_pkts_to_create (mcl_cb *const mclcb, + mcl_block *blk); + + /** + * Return the number of pending FEC creation requests for this block. + * This is the sum of packets to create over all pending FEC jobs for + * this block. + * @param blk block concerned + * @return number of FEC packets that are to be created + */ + INT32 get_pending_fec_creation_req (mcl_block *blk); + + /** + * Increments the number of pending FEC creation requests for this + * block. + * Used after the creation of a FEC job. + * @param blk block concerned + * @param fec_to_create + */ + void incr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_to_create); + + /** + * Decrements the number of pending FEC creation requests for this + * block. + * Used after the completion of a FEC job. + * @param blk block concerned + * @param fec_created + */ + void decr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_created); + + /** + * Encode the block and create the requested number of new FEC packets. + * Encoding is done asynchronously by the fec_encoding_thread + * and the results inserted automatically in the sender's + * transmission queue. + * @param mclcb + * @param blk block for which FEC packets must be created + * @param fec_desired number of FEC packets that must be created + * @return < 0 if error, the number of FEC symbols created if ok + */ + INT32 encode (mcl_cb *const mclcb, + mcl_block *blk, + INT32 fec_desired); + + /** + * Decode the block. + * Decoding is done immediately. + * @return < 0 if error, the number of FEC symbols created if ok + */ + INT32 decode (mcl_cb *const mclcb, + mcl_block *blk); + + + /** + * Return the thread id. + * Required to enable a safe thread destruction. + */ + mcl_thread_t get_fec_encoding_thread_id (); + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + /** + * Performs FEC encoding for this block. + * This function may be called several times for the same block (even + * if calling it once may be faster), for instance to satisfy + * additional retransmission requests. + * @param blk block for which FEC packets must be created + * @param start_index index of the first (inclusive) FEC packet + * to create + * @param fec_desired number of FEC packets that must be created + * from start_index + * @returns number of FEC packets created if ok, < 0 if error. + */ + INT32 fec_encoding_func (mcl_cb *const mclcb, + mcl_block *blk, + INT32 start_index, + INT32 fec_desired); + + + /****** Private Attributes ********************************************/ + bool initialized; /** true when encoding thread is started. */ + + INT32 fec_codec; /** + * Codec to use for this session. + * Can be one of MCL_FEC_CODE_NULL, ...RSE, + * ...LDGM, ...LDPC. + */ + INT32 max_k[MCL_FEC_CODE_MAX_NB]; /** Max k value. FEC dependant */ + INT32 max_n[MCL_FEC_CODE_MAX_NB]; /** Max n value. FEC dependant */ + INT32 cur_k[MCL_FEC_CODE_MAX_NB]; /** k value currently in use. */ + INT32 cur_n[MCL_FEC_CODE_MAX_NB]; /** n value currently in use. */ + float max_fratio; /** Maximum FEC ratio defined as n/k. */ + +#if 0 + INT32 max_k; /** max value; FEC code dependant... */ + INT32 max_n; /** max value; FEC code dependant... */ + INT32 cur_k; /** k value currently in use. */ + INT32 cur_n; /** n value currently in use. */ +#endif + + /** + * FEC job list. + */ + mcl_fec_job_list fec_job_list; + + /** + * FEC thread. + */ + mcl_fec_thread fec_encoding_thread; +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline void +mcl_fec_job_list::lock (void) +{ + mcl_lock (&(this->list_lock)); +} + +inline void +mcl_fec_job_list::unlock (void) +{ + mcl_unlock (&(this->list_lock)); +} + +inline mcl_thread_t +mcl_fec_thread::get_fec_thread_id () +{ + return this->fec_thread_id; +} + +inline INT32 +mcl_fec::get_max_k () const +{ + return this->max_k[this->fec_codec]; +} + +inline INT32 +mcl_fec::get_max_n () const +{ + return this->max_n[this->fec_codec]; +} + +inline INT32 +mcl_fec::get_k (void) const +{ + return this->cur_k[this->fec_codec]; +} + +inline void +mcl_fec::set_k (const INT32 k) +{ + ASSERT(k <= max_k[this->fec_codec]); + ASSERT(k > 0); + ASSERT(k <= cur_n[this->fec_codec]); + this->cur_k[this->fec_codec] = k; +} + +inline INT32 +mcl_fec::get_n () const +{ + return this->cur_n[this->fec_codec]; +} + +inline void +mcl_fec::set_n (const INT32 n) +{ + ASSERT(n <= max_n[this->fec_codec]); + ASSERT(n > 0); + ASSERT(cur_k[this->fec_codec] <= n); + this->cur_n[this->fec_codec] = n; +} + +inline float +mcl_fec::get_max_fec_ratio () const +{ + return this->max_fratio; +} + +inline mcl_thread_t +mcl_fec::get_fec_encoding_thread_id () +{ + return this->fec_encoding_thread.get_fec_thread_id(); +} + +inline INT32 +mcl_fec::get_pending_fec_creation_req (mcl_block *blk) +{ + return (blk->pending_fec_creation_req); +} + +inline void +mcl_fec::incr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_to_create) +{ + blk->pending_fec_creation_req += fec_to_create; +} + +inline void +mcl_fec::decr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_created) +{ + blk->pending_fec_creation_req -= fec_created; +} + +#endif // MCL_FEC_H + diff --git a/src/norm/mcl_block.cpp b/src/norm/mcl_block.cpp new file mode 100644 index 0000000..8af58c2 --- /dev/null +++ b/src/norm/mcl_block.cpp @@ -0,0 +1,166 @@ +/* $Id: mcl_block.cpp,v 1.6 2004/03/09 15:16:21 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * default destructor + */ +mcl_block::~mcl_block () +{ + this->remove_and_free_all_data_dus(NULL); + this->remove_and_free_all_fec_dus(NULL); +} + + +bool +mcl_block::check_if_completed_and_process (mcl_cb *const mclcb) +{ + INT32 nb; /* total nb of DUs received */ + + if (this->get_rx_status() >= BLK_STATUS_COMPLETED) { + TRACELVL(5, (mcl_stdout, + " mcl_block::check_if_completed_and_process: already completed\n")) + return true; + } + ASSERT(this->get_rx_status() == BLK_STATUS_IN_PROGRESS); + nb = this->du_in_list + this->fec_du_in_list; + if (nb >= this->du_nb) { + if (mclcb->rx_window.postpone_fec_decoding) { + /* ok, we rx enough data or FEC DU, just mark it */ + this->rx_status = BLK_STATUS_COMPLETED; + } else { + /* ok, we rx enough data or FEC DU, so decode */ + mclcb->fec.decode(mclcb, this); + this->rx_status = BLK_STATUS_DECODED; + } + TRACELVL(5, (mcl_stdout, + " mcl_block::check_if_completed_and_process: yes\n")) + return true; + } else { + TRACELVL(5, (mcl_stdout, + " mcl_block::check_if_completed_and_process: %d DUs expected, %d recvd\n", + this->du_nb, nb)) + return false; + } +} + + +/** + * Check if this block is completed and return the number of missing + * DUs if any. + * Used by a receiver, in particular during NACK/ACK processing. + * @param mclcb + * @return number of missing DUs, or 0 if already completed. + */ +INT32 +mcl_block::get_number_of_missing_dus (mcl_cb *const mclcb) +{ + INT32 missing; /* nb of missing DUs */ + + if (this->get_rx_status() >= BLK_STATUS_COMPLETED) { + TRACELVL(5, (mcl_stdout, + " mcl_block::get_number_of_missing_dus: already completed\n")) + return 0; + } + missing = this->du_nb - (this->du_in_list + this->fec_du_in_list); + if (missing <= 0) { + /* for an unknown reason the block status has not been + * updated, so do it */ + this->check_if_completed_and_process(mclcb); + TRACELVL(5, (mcl_stdout, + " mcl_block::get_number_of_missing_dus: already completed\n")) + return 0; + } + TRACELVL(5, (mcl_stdout, + " mcl_block::get_number_of_missing_dus: %d DUs expected, %d missing\n", + this->du_nb, missing)) + return missing; +} + + +void +mcl_block::remove_and_free_all_data_dus (mcl_cb *const mclcb) +{ + + INT32 rem; // remaining nb of DUs that need to be free'ed + mcl_du *du; // DU being free'ed + mcl_du *ndu; // next DU to free + + if ((rem = this->get_du_nb_in_list()) <= 0) { + /* nothing in list */ + return; + } + du = this->du_head; + ASSERT(du); + if (mclcb) { + TRACELVL(5, (mcl_stdout, "-> mcl_block::remove_and_free_all_data_dus: %d to free\n", this->get_du_nb_in_list())) + /* update stats simply, assuming all DUs of same size */ + mclcb->stats.buf_space -= rem * du->len; + } + for (; rem > 0; rem--, du = ndu) { + ASSERT(du); + ndu = du->get_next(); + delete du; + } + this->du_head = NULL; + this->du_in_list = 0; + if (mclcb) { + TRACELVL(5, (mcl_stdout, "<- mcl_block::remove_and_free_all_data_dus:\n")); + } +} + + +/** + * Remove and free all FEC DUs of the list. + * Can be called both by a sender or a receiver. + */ +void +mcl_block::remove_and_free_all_fec_dus (mcl_cb *const mclcb) +{ + INT32 rem; // remaining nb of DUs that need to be free'ed + mcl_du *du; // DU being free'ed + mcl_du *ndu; // next DU to free + + if ((rem = this->get_fec_du_nb_in_list()) <= 0) { + /* nothing in list */ + return; + } + du = this->fec_du_head; + ASSERT(du); + if (mclcb) { + TRACELVL(5, (mcl_stdout, + "-> mcl_block::remove_and_free_all_fec_dus: %d to free\n", rem)) + /* update stats simply, assuming all DUs of same size */ + mclcb->stats.buf_space -= rem * du->len; + } + for (; rem > 0; rem--, du = ndu) { + ndu = du->get_next(); + delete du; + } + this->fec_du_head = NULL; + this->fec_du_in_list = 0; + if (mclcb) { + TRACELVL(5, (mcl_stdout, "<- mcl_block::remove_and_free_all_fec_dus:\n")); + } +} + diff --git a/src/norm/mcl_block.h b/src/norm/mcl_block.h new file mode 100644 index 0000000..e7f27aa --- /dev/null +++ b/src/norm/mcl_block.h @@ -0,0 +1,308 @@ +/* $Id: mcl_block.h,v 1.4 2004/02/18 07:56:18 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + + +#ifndef MCL_BLOCK_H +#define MCL_BLOCK_H + + +/** + * Possible block status at a sender. + * The possible transitions are the following: + * NIL -> IN_PROGRESS -> FINISH_TX -> DONE + */ +enum mcl_block_tx_status { + BLK_TSTATUS_NIL = 0, /* void status */ + BLK_TSTATUS_IN_PROGRESS = 1, /* DUs are being transmitted */ + BLK_TSTATUS_FINISH_TX = 2, /* all DUs from this block have been + sent once, currently in repair mode*/ + BLK_TSTATUS_DONE = 3 /* totally and reliably sent, buffer + freed */ +}; + +/** + * Possible block status at a receiver. + * The possible transitions are the following: + * NIL -> IN_PROGRESS -> COMPLETED -> DECODED -> DELIVERED + */ +enum mcl_block_rx_status { + BLK_STATUS_NIL = 0, /* void status */ + BLK_STATUS_IN_PROGRESS = 1, /* not yet ready */ + BLK_STATUS_COMPLETED = 2, /* received all DUs for this block */ + BLK_STATUS_DECODED = 3, /* COMPLETED and FEC decoding done */ + BLK_STATUS_DELIVERED = 4 /* sent to the receiving application */ +}; + + +/** + * Source Data Block + * They are the result of the segmentation of ADUs into several + * blocks of size appropriate to the FEC code. + */ +class mcl_block { + +public: + /****** Public Members ************************************************/ + /* + * There is no default constructor for performance reasons... + * The class is assumed to be manually reset to 0 after creation. + * see mcl_adu::segment_for_tx() + */ + + /** + * default destructor + */ + ~mcl_block (); + + /** + * Return the status of a transmitted block. + */ + mcl_block_tx_status get_tx_status () const; + + /** + * Set the new status of a transmitted block. + */ + void set_tx_status (mcl_block_tx_status new_status); + + /** + * Return the status of a received block. + */ + mcl_block_rx_status get_rx_status () const; + + /** + * Set the new status of a received block. + */ + void set_rx_status (mcl_block_rx_status new_status); + + /** + * Check if this block is completed and take appropriate measures. + * Used by a receiver when a new non-duplicated DU is received for + * a block. + * @param mclcb + * @return true if completed and appropriate measures taken, + * false otherwise. + */ + bool check_if_completed_and_process (mcl_cb *const mclcb); + + /** + * Check if this block is completed and return the number of missing + * DUs if any. + * Used by a receiver, in particular during NACK/ACK processing. + * @param mclcb + * @return number of missing DUs, or 0 if already completed. + */ + INT32 get_number_of_missing_dus (mcl_cb *const mclcb); + + /** + * Set the head of the DU ordered list. + */ + void set_du_head (class mcl_du *const du); + + /** + * Get the head of the DU ordered list. + */ + class mcl_du *get_du_head () const; + + /** + * Insert a DU in the data DU ordered list. + * @param mclcb + * @return MCL_OK if inserted, MCL_ERROR if the DU was already + * in list or if an error occured + */ + mcl_error_status insert_in_du_list (mcl_cb *const mclcb, + class mcl_du *du); + + /** + * Set the head of the FEC DU ordered list. + * @param du new DU head + */ + void set_fec_du_head (class mcl_du *const du); + + /** + * Get the head of the FEC DU ordered list. + * @return head + */ + class mcl_du *get_fec_du_head () const; + + /** + * Get the tail of the FEC DU ordered list. + * @return tail + */ + class mcl_du *get_fec_du_tail () const; + + /** + * Insert a DU in the FEC DU ordered list. + * @param mclcb + * @return MCL_OK if inserted, MCL_ERROR if the DU was already + * in list or if an error occured + */ + mcl_error_status insert_in_fec_du_list (mcl_cb *const mclcb, + class mcl_du *du); + + /** + * Remove and free all data DUs of the list. + * Used only by receivers. + * @param mclcb + */ + void remove_and_free_all_data_dus (mcl_cb *const mclcb); + + /** + * Remove and free all FEC DUs of the list. + * Can be called both by a sender or a receiver. + * @param mclcb + */ + void remove_and_free_all_fec_dus (mcl_cb *const mclcb); + + /** + * Return the number of data DUs in the data list. + */ + INT32 get_du_nb_in_list (); + + /** + * Return the number of FEC DUs in the FEC list. + */ + INT32 get_fec_du_nb_in_list (); + + /****** Public Attributes *********************************************/ + class mcl_adu *adu; // ADU to which this block belongs + UINT32 seq; // block sequence number + INT32 len; // number of bytes in this block + + INT32 du_nb; // nb of data DUs that compose this blk + // (different from avail DUs in lists) + /* sender specific fields */ + INT32 pending_fec_creation_req; //nb pending FEC pkt creations + +private: + /****** Private Attributes ********************************************/ + /* + * DU lists + */ + class mcl_du *du_head; // first DU of this block in list/tab + class mcl_du *fec_du_head; // first FEC DU of this block in list + INT32 du_in_list; // nb of non-FEC DUs avail (!= du_nb) + INT32 fec_du_in_list; // nb of FEC DUs available in list + + mcl_block_tx_status tx_status; // tx status + mcl_block_rx_status rx_status; // rx status (completed/decoded/..) + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline void +mcl_block::set_du_head (class mcl_du *const du) +{ + this->du_head = du; +} + +inline class mcl_du * +mcl_block::get_du_head () const +{ + return this->du_head; +} + +inline void +mcl_block::set_fec_du_head (class mcl_du *const du) +{ + ASSERT(du); + this->fec_du_head = du; +} + +inline class mcl_du * +mcl_block::get_fec_du_head () const +{ + return this->fec_du_head; +} + +inline class mcl_du * +mcl_block::get_fec_du_tail () const +{ + if (this->fec_du_head) + return this->fec_du_head->get_prev(); + else + return NULL; +} + +inline mcl_block_tx_status +mcl_block::get_tx_status () const +{ + return this->tx_status; +} + +inline void +mcl_block::set_tx_status (mcl_block_tx_status new_status) +{ + this->tx_status = new_status; +} + + +inline mcl_block_rx_status +mcl_block::get_rx_status () const +{ + return this->rx_status; +} + +inline void +mcl_block::set_rx_status (mcl_block_rx_status new_status) +{ + this->rx_status = new_status; +} + +inline mcl_error_status +mcl_block::insert_in_du_list (mcl_cb *const mclcb, + class mcl_du *du) +{ + if (du->insert_in_list(mclcb, &(this->du_head)) == MCL_OK) { + this->du_in_list++; + return MCL_OK; + } else + return MCL_ERROR; +} + +inline mcl_error_status +mcl_block::insert_in_fec_du_list (mcl_cb *const mclcb, + class mcl_du *du) +{ + if (du->insert_in_list(mclcb, &(this->fec_du_head)) == MCL_OK) { + this->fec_du_in_list++; + return MCL_OK; + } else + return MCL_ERROR; +} + +inline INT32 +mcl_block::get_du_nb_in_list () +{ + return this->du_in_list; +} + +inline INT32 +mcl_block::get_fec_du_nb_in_list () +{ + return this->fec_du_in_list; +} + +#endif // !MCL_BLOCK_H + diff --git a/src/norm/mcl_cb.cpp b/src/norm/mcl_cb.cpp new file mode 100644 index 0000000..7abf392 --- /dev/null +++ b/src/norm/mcl_cb.cpp @@ -0,0 +1,228 @@ +/* $Id: mcl_cb.cpp,v 1.3 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + +/* + * mcl_cb class implementation + */ + +mcl_cb *mclcb_tab[MAX_NB_MCLCB]; + + +/** + * One time initialization of the mclcb_tab. + */ +void +mcl_init_mclcb_tab (void) +{ +#ifdef DEBUG + static bool init = false; + + ASSERT(init == false); // check that it is called only once + init = true; +#endif + /* the session control block table */ + memset(mclcb_tab, 0, sizeof(mclcb_tab)); +} + + +/** + * Session control block constructor. + */ +mcl_cb::mcl_cb (mcl_tx_rx_mode mode) +{ + mcl_global_init(); // global MCL initialization (if not + // already performed + // initialize everything first... + this->id = 0; + this->fully_initialized = false; + this->tx_rx_mode = MCL_INVALID; + this->verbosity_level = 0; + //this->verbosity_level = 6; // for tests... set to maximum + this->stats_level = 0; + this->max_datagram_size = MAX_DATAGRAM_SIZE; + this->payload_size = MAX_PAYLOAD_SIZE; + + // default tx rate init. Must be done after datagram_size init. + //this->tx.set_bps_tx_rate(this, (float)10000000.0); + this->tx.set_bps_tx_rate(this, (float)1000000.0); + //this->tx.set_bps_tx_rate(this, (float)32000.0); + + // trick to get a unique identifier in the file descriptor space + if ((this->id = (INT32)dup(0)) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_cb::mcl_cb: ERROR cannot create a new session identifier\n")) + goto bad; + } + if (this->id >= MAX_NB_MCLCB) { + PRINT_ERR((mcl_stderr, + "mcl_cb::mcl_cb: ERROR too many opens, MCL file descriptor space full\n")) + goto bad; + } + // store the new mclcb in the tab + ASSERT(mclcb_tab[this->id] == NULL); + mclcb_tab[this->id] = this; + + // initialize the mode + this->tx_rx_mode = mode; + switch (mode) { + case MCL_IS_A_SENDER_ONLY: + this->fsm.update_tx_state(this, TEVENT_OPEN_CALLED); + // can't call init_sender() here because of param parsing + break; + case MCL_IS_A_RECEIVER_ONLY: + this->fsm.update_rx_state(this, REVENT_OPEN_CALLED); + // can't call init_receiver() here because of param parsing + break; + default: + PRINT_ERR((mcl_stderr, "mcl_cb::mcl_cb: ERROR unknown mode %d\n", + mode)) + goto bad; + } + + // global session lock... there's only one! + mcl_init_lock(&(this->session_lock)); + + // ok, return + return; + +bad: + PRINT_ERR((mcl_stderr, "mcl_cb::mcl_cb: failed\n")) + exit (-1); +} + + +/** + * Destructor. + */ +mcl_cb::~mcl_cb () +{ + mclcb_tab[this->id] = NULL; + this->id = 0; + this->fully_initialized = false; +} + + +mcl_error_status +mcl_cb::set_verbosity (INT32 level) +{ + if (level < 0 || level > 6) { + PRINT_ERR((mcl_stderr, "mcl_cb::set_verbosity: level out of range (expected [0;6], got %d).\n", (int)level)) + return MCL_ERROR; + } + this->verbosity_level = (INT8)level; + return MCL_OK; +} + + +mcl_error_status +mcl_cb::set_stats_level (INT32 level) +{ + if (level < 0 || level > 2) { + PRINT_ERR((mcl_stderr, "mcl_cb::set_verbosity: level out of range (expected [0;1], got %d).\n", (int)level)) + return MCL_ERROR; + } + this->stats_level = (INT8)level; + return MCL_OK; +} + + +/** + * Finish the initialization of the session. + */ +mcl_error_status +mcl_cb::finish_session_init () +{ +#ifdef DEBUG + mcl_cb *mclcb = this; // required by TRACELVL +#endif + + TRACELVL(5, (mcl_stdout, "-> mcl_cb::finish_session_init:\n")) + ASSERT((!this->fully_initialized)) + this->fully_initialized = true; + /* + * perform socket initialization now... + */ + if (this->ses_channel.sock_init(this) != MCL_OK) { + PRINT_ERR((mcl_stderr, + "mcl_cb::finish_session_init: ERROR: socket initialization failed\n")) + mcl_exit(1); + } + /* + * start the reception thread. + * required both by senders and receivers. + */ + this->rx_thread.start(this); + + TRACELVL(5, (mcl_stdout, "<- mcl_cb::finish_session_init:\n")) + + return MCL_OK; +} + + +void +mcl_cb::free_everything () +{ + /* free ADUs and their buffers */ + this->tx.free_all_adu(this); + /* close all the opened sockets */ + this->ses_channel.sock_close(this); +} + + +mcl_error_status +mcl_cb::set_max_datagram_size (INT32 sz) +{ + // sanity checks... + if (sz < MIN_NORM_HDR_SIZE || sz > MAX_DATAGRAM_SIZE) { + PRINT_ERR((mcl_stderr, + "mcl_cb::set_max_datagram_size: size out of range (expected [%d;%d], got %d).\n", + MIN_NORM_HDR_SIZE, MAX_DATAGRAM_SIZE, sz)) + return MCL_ERROR; + } + this->max_datagram_size = sz; + this->payload_size = this->max_datagram_size - MAX_NORM_HDR_SIZE_FOR_DATA; + return MCL_OK; +} + + +mcl_error_status +mcl_cb::set_payload_size (INT32 sz) +{ + // sanity checks... + if (sz < 1 || sz > MAX_PAYLOAD_SIZE) { + PRINT_ERR((mcl_stderr, + "mcl_cb::set_payload_size: size out of range (expected [1;%d], got %d).\n", + MAX_PAYLOAD_SIZE, sz)) + return MCL_ERROR; + } + if (sz >= this->max_datagram_size) { + PRINT_ERR((mcl_stderr, + "mcl_cb::set_payload_size: size %d cannot be larger than current max datagram size %d.\n", + sz, this->max_datagram_size)) + return MCL_ERROR; + } + this->payload_size = sz; + return MCL_OK; +} + + diff --git a/src/norm/mcl_cb.h b/src/norm/mcl_cb.h new file mode 100644 index 0000000..84d4d1a --- /dev/null +++ b/src/norm/mcl_cb.h @@ -0,0 +1,370 @@ +/* $Id: mcl_cb.h,v 1.3 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_CB_H +#define MCL_CB_H + +#include "mcl_node.h" +#include "mcl_fsm.h" +#include "mcl_timer.h" +#include "../common/mcl_periodic_timer.h" +#include "mcl_periodic_proc.h" +#include "mcl_fec.h" +#include "mcl_stats.h" +#include "mcl_ses_channel.h" +#include "mcl_norm_pkt_mgmt.h" + +#include "mcl_tx.h" +#include "mcl_tx_window.h" +#include "mcl_tx_ctrl.h" +#include "mcl_tx_storage.h" +#include "mcl_group_mgmt.h" + +#include "mcl_rx.h" +#include "mcl_rx_window.h" +#include "mcl_rx_thread.h" +#include "mcl_rx_ctrl.h" +#include "mcl_rx_storage.h" + + +/** Possible session modes. */ +enum mcl_tx_rx_mode { + MCL_INVALID, + MCL_IS_A_SENDER_ONLY, + MCL_IS_A_RECEIVER_ONLY + //MCL_IS_SENDER_AND_RECEIVER not yet supported +}; + + +/** + * Control Block Class for an MCL_NORM session. + * Contains all the variables, classes, member functions etc. required for + * a session. + */ +class mcl_cb { + +public: + + /****** Public Members ************************************************/ + /** + * Constructor. + * Perform pre-initialization of the session. + * At completion, the session is NOT fully initialized, but + * sufficiently to enable most tasks to be performed (e.g all + * threads are created). + * @param mode determines if this is a sender or receiver + */ + mcl_cb (mcl_tx_rx_mode mode); + + /** Destructor */ + ~mcl_cb (); + + /** + * Returns the local MCL session id. + * The session identifier is set once, at session creation. + * This is different from the node NORM id. + * @return session id + */ + INT32 get_id(); + + /** + * Get the tx/rx mode for this session. + * @return mode + */ + mcl_tx_rx_mode get_mode (); + + /** + * Is this session a sender's session. + * @return boolean + */ + bool is_a_sender (); + + /** + * Is this session a receiver's session. + * @return boolean + */ + bool is_a_receiver (); + + /** + * Set the verbosity level. + * @param level + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_verbosity (INT32 level); + + /** + * Get the verbosity level. + * @return verbosity level + */ + INT32 get_verbosity (); + + /** + * Set the statistic level + * @param level + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_stats_level (INT32 level); + + /** + * Get the statistic level. + * @return statistic level + */ + INT32 get_stats_level (); + + /** + * Set the session lock. + * There is one lock per MCL session. Their total number is equal + * to the number of concurrent sessions. + */ + void lock (); + + /** + * Try to set the session lock. + * There is one lock per MCL session. Their total number is equal + * to the number of concurrent sessions. + * @return return EBUSY if not possible, 0 if ok + * + */ + INT32 trylock (); + + /** + * Release the session lock. + */ + void unlock (); + + /** + * Finish the initialization of the session if not already done. + * This end of init is done only once. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status finish_session_init_if_needed (); + + /** + * True once the session if fully initialized. + * @return boolean + */ + bool is_fully_initialized (); + + /** + * Free everything. + * This is done at the very last stage, at the end of session close + * or abort. + */ + void free_everything (); + + /** + * Set the maximum datagram size (in bytes) and adjusts the payload + * size in consequence. + * A datagram includes the payload (if any) plus the NORM header. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_max_datagram_size (INT32 sz); + + /** + * Get the maximum datagram size (in bytes). + * A datagram includes the payload (if any) plus the NORM header. + * @return maximum datagram size in bytes + */ + INT32 get_max_datagram_size () const; + + /** + * Set the payload size (in bytes). + * Only the data payload of the NORM datagram is considered here. + * @return Completion status (MCL_OK or MCL_ERROR). + * + */ + mcl_error_status set_payload_size (INT32 sz); + + /** + * Get the payload size (in bytes). + * Only the data payload of the NORM datagram is considered here. + * Can be set independantly of the max_datagram_size but cannot + * be larger than this latter. + * @return payload size in bytes + */ + INT32 get_payload_size () const; + + + /****** Public Attributes *********************************************/ + /* + * All the classes required by a session follow... + */ + /* + * Shared by senders and receivers + */ + class mcl_node node; + class mcl_fsm fsm; + class mcl_timer timer; + class mcl_periodic_proc periodic_proc; + class mcl_fec fec; + class mcl_stats stats; + class mcl_ses_channel ses_channel; // session channel + class mcl_norm_pkt_mgmt norm_pkt_mgmt; + + /* + * Sender specific + */ + class mcl_tx tx; // Transmission class + class mcl_group_mgmt group_mgmt; + class mcl_tx_ctrl tx_ctrl; // Performs all NACK/ACK/INFO + // control tasks + class mcl_tx_window tx_window; // Store ADUs/DUs to send + //class mcl_tx_pgmcc tx_pgmcc; not yet... + //class mcl_tx_tfmcc tx_tfmcc; not yet... + class mcl_tx_storage tx_storage; + + /* + * Receiver specific + */ + class mcl_rx rx; // Reception class + class mcl_rx_thread rx_thread; // Reception thread + class mcl_rx_ctrl rx_ctrl; // Performs all NACK/ACK/INFO + // control tasks + class mcl_rx_window rx_window; // Store ADUs/DUs received + //class mcl_rx_pgmcc rx_pgmcc; not yet... + //class mcl_rx_tfmcc rx_tfmcc; not yet... + class mcl_rx_storage rx_storage; + + +private: + /****** Private Members ***********************************************/ + /** + * Finish the initialization of the session. + * This function is called by finish_session_init_if_needed() + * after that all the appropriate params have been set up with + * mcl_ctl(). + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status finish_session_init (); + + /****** Private Attributes ********************************************/ + bool fully_initialized; // true when session is fully init'ed + // ie. after finish_session_init() + INT32 id; // MCL session identifier + mcl_tx_rx_mode tx_rx_mode; + INT8 verbosity_level;// debug trace level + INT8 stats_level; // statistics level + mcl_mutex_t session_lock; // global session lock + + INT32 max_datagram_size; // max datagram size for tx and rx + INT32 payload_size; // default payload size for tx and rx +}; + + +/** + * Table containing the various control blocks of the sessions. + * There can be at most MCLCB_MAX_ID simultaneous sessions in an MCL-NORM + * instance. + */ +extern mcl_cb *mclcb_tab[MAX_NB_MCLCB]; + +/** One time initialization function for the mclcb table. */ +extern void mcl_init_mclcb_tab (void); + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +inline INT32 +mcl_cb::get_id() +{ + return this->id; +} + +inline mcl_tx_rx_mode +mcl_cb::get_mode () +{ + return this->tx_rx_mode; +} + +inline bool +mcl_cb::is_a_sender () +{ + return (this->tx_rx_mode == MCL_IS_A_SENDER_ONLY); +} + +inline bool +mcl_cb::is_a_receiver () +{ + return (this->tx_rx_mode == MCL_IS_A_RECEIVER_ONLY); +} + +inline INT32 +mcl_cb::get_verbosity () +{ + return (INT32) this->verbosity_level; +} + +inline INT32 +mcl_cb::get_stats_level () +{ + return (INT32) this->stats_level; +} + +inline void +mcl_cb::lock () +{ + mcl_lock(&(this->session_lock)); +} + +inline INT32 +mcl_cb::trylock () +{ + return mcl_trylock(&(this->session_lock)); +} + +inline void +mcl_cb::unlock () +{ + mcl_unlock(&(this->session_lock)); +} + +inline mcl_error_status +mcl_cb::finish_session_init_if_needed () +{ + if (this->fully_initialized) + return MCL_OK; + else + return (this->finish_session_init()); +} + +inline bool +mcl_cb::is_fully_initialized () +{ + return this->fully_initialized; +} + +inline INT32 +mcl_cb::get_max_datagram_size () const +{ + return this->max_datagram_size; +} + +inline INT32 +mcl_cb::get_payload_size () const +{ + return this->payload_size; +} + +#endif // MCL_CB_H + diff --git a/src/norm/mcl_du.cpp b/src/norm/mcl_du.cpp new file mode 100644 index 0000000..285a3eb --- /dev/null +++ b/src/norm/mcl_du.cpp @@ -0,0 +1,150 @@ +/* $Id: mcl_du.cpp,v 1.3 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * default destructor + */ +mcl_du::~mcl_du () +{ + if (this->pkt) { + /* + * RECEIVER + */ + // this is a DU recvd from net, buffer is + // in the du->pkt and free'd there + delete this->pkt; + this->pkt = NULL; + this->data = 0; + } else { + /* + * SENDER + */ + if (this->is_fec) { + free(this->data); + this->data = NULL; + } + // else do nothing since all DUs point to the same buffer + // allocated as a whole during ADU submission. + } +} + + +#if 0 +/** + * overloaded destructor. + * Called when the du->block->adu chain is not fully initialized. + * @param type differentiate between TX and RX ADU + */ +mcl_du::~mcl_du (mcl_tx_or_rx type) +{ + if (type == MCL_TX) { + /* + * SENDER + */ + if (this->is_fec) { + free(this->data); + this->data = NULL; + } + // else do nothing since DU objects and data have been + // allocated as a whole during submission. + } else { + /* + * RECEIVER + */ + if (this->pkt) { + // this is a DU recvd from net, buffer is + // in the du->pkt and free'd there + delete this->pkt; + this->pkt = NULL; + this->data = 0; + } else if (this->data) { + // this is a reconstructed data DU + free(this->data); + } else { + ASSERT(0); // error!!! + } + } +} +#endif // 0 + + +/** + * Insert a du in an ordered list according to the sequence number. + * Called with the appropriate list head parameter. + * Insert the du at its location (i.e. to comply + * with the increasing seq # property) in the list. + * @param mclcb + * @param head pointer to the list head pointer + * @return completion status: MCL_OK if inserted, or MCL_ERROR + * if already present in list. + */ +mcl_error_status +mcl_du::insert_in_list (mcl_cb *const mclcb, + mcl_du **head) +{ + mcl_du *pdu, *ndu; /* insert du between prev_du, next_du */ + + ASSERT(head); + ASSERT(this->next == NULL && this->prev == NULL); /* single DU to add */ + TRACELVL(5, (mcl_stdout, "-> mcl_du::insert_in_list: du=x%x\n", (int)this)) + /* + * find last DU in list, i.e. with highest seq nb + */ + if (*head == NULL || (*head)->prev == NULL) { + /* first DU in empty list */ + *head = this; + this->next = this->prev = this; + TRACELVL(5, (mcl_stdout, "<- mcl_du::insert_in_list: first\n")) + return MCL_OK; + } + pdu = (*head)->prev; + ndu = pdu->next; + /* + * find the proper location of du in the list to make + * sure seq numbers are always increasing + */ + while (this->seq < pdu->seq) { + ndu = pdu; + pdu = pdu->prev; + if (ndu == *head) { + /* we have cycled ! du is the new list head */ + *head = this; + break; + } + } + if (this->seq == pdu->seq) { + /* DU already received */ + TRACELVL(5, (mcl_stdout, "<- mcl_du::insert_in_list: already rcvd\n")) + return MCL_ERROR; + } else { + /* new DU */ + pdu->next = this; + this->prev = pdu; + this->next = ndu; + ndu->prev = this; + TRACELVL(5, (mcl_stdout, "<- mcl_du::insert_in_list: new\n")) + return MCL_OK; + } +} + diff --git a/src/norm/mcl_du.h b/src/norm/mcl_du.h new file mode 100644 index 0000000..b49b94b --- /dev/null +++ b/src/norm/mcl_du.h @@ -0,0 +1,208 @@ +/* $Id: mcl_du.h,v 1.2 2003/12/17 15:56:01 roca Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_DU_H +#define MCL_DU_H + + +/** + * Data Unit (DU) + * They are the result of the segmentation of a block (i.e. ADU chunck) + * and identify a sequence of bytes. + * They can either contain plain data or redundant FEC data. + * + * Four kinds of DUs exist: + * SENDER + * - data DUs: their data field points to an internal copy of the + * ADU's data buffer. All the DUs of an ADU are allocated at + * the same time, in a table of DU objects. There is no default + * DU constructor in order to reset this whole DU table at once + * (rather than individually, which is much slower!) + * - FEC DUs: their data field points to a malloc'd buffer. + * These DUs are allocated individually. + * RECEIVER + * - data and FEC DUs received from network: their pkt field points + * to the rx_packet object which owns the data buffer. + * - reconstructed data DUs: no pkt field, the data field points to + * a malloc'd buffer. These DUs are allocated individually. + */ + +class mcl_du { + +public: + /****** Public Members ************************************************/ + /* + * There is no default constructor for performance reasons... + * The class is assumed to be manually reset to 0 after creation. + * see mcl_adu::segment_for_tx() + */ + + /** + * default destructor + */ + ~mcl_du (); + + /** + * overloaded destructor. + * Called when the du->block->adu chain is not fully initialized. + * @param type differentiate between TX and RX ADU + */ + //mcl_du::~mcl_du (mcl_tx_or_rx type); + + /** + * Manipulate the main list pointers. + */ + void set_prev (mcl_du *const p); + mcl_du *get_prev () const; + void set_next (mcl_du *const n); + mcl_du *get_next () const; + + /** + * Same as above with the second (sender specific) list. + */ + void set_tx_prev (mcl_du *const p); + mcl_du *get_tx_prev () const; + void set_tx_next (mcl_du *const n); + mcl_du *get_tx_next () const; + + /** + * Insert a du in an ordered list according to the sequence number. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + * @return completion status: MCL_OK if inserted, or MCL_ERROR + * if already present in list. + */ + mcl_error_status insert_in_list (mcl_cb *const mclcb, + mcl_du **head); + +#if 0 + /** + * Remove a du from a list. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ + mcl_error_status remove_from_list (mcl_cb *const mclcb, + mcl_du **head); + + /** + * Find a du in a list with its sequence number. + * @param mclcb + * @param head pointer to the list head pointer + * @param seq ADU seq number + * @return returns a pointer to the adu if found, NULL otherwise + */ + mcl_adu *find_in_list (mcl_cb *const mclcb, + mcl_du *head, + UINT32 seq); +#endif // 0 + + /****** Public Attributes *********************************************/ + mcl_block *block; /* block to which this DU belongs */ + char *data; /* ptr to data in buffer */ + UINT32 seq; /* sequence number of this DU */ + UINT16 len; /* number of bytes in this DU */ + bool is_fec; /* is it a FEC or a data DU? */ + /* rx specific field */ + class mcl_rx_pkt *pkt; // object containing the packet recvd + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + /** + * Pointers to DU and FEC DU lists of a block. + * These are the only lists can should use these pointers! + */ + mcl_du *prev, *next; + + /* tx specific field */ + /** + * Pointer to second DU and FEC DU list. + * Used by the tx_window service! + */ + mcl_du *tx_prev, *tx_next; +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +/** + * Manipulate the main list pointers. + */ + +inline void +mcl_du::set_prev (mcl_du *const p) +{ + this->prev = p; +} + +inline mcl_du * +mcl_du::get_prev () const +{ + return this->prev; +} + +inline void +mcl_du::set_next (mcl_du *const n) +{ + this->next = n; +} + +inline mcl_du * +mcl_du::get_next () const +{ + return this->next; +} + + +/** + * Same as above with the second (sender specific) list. + */ + +inline void +mcl_du::set_tx_prev (mcl_du *const p) +{ + this->tx_prev = p; +} + +inline mcl_du * +mcl_du::get_tx_prev () const +{ + return this->tx_prev; +} + +inline void +mcl_du::set_tx_next (mcl_du *const n) +{ + this->tx_next = n; +} + +inline mcl_du * +mcl_du::get_tx_next () const +{ + return this->tx_next; +} + +#endif // !MCL_DU_H + diff --git a/src/norm/mcl_fec.cpp b/src/norm/mcl_fec.cpp new file mode 100644 index 0000000..572dd9a --- /dev/null +++ b/src/norm/mcl_fec.cpp @@ -0,0 +1,774 @@ +/* $Id: mcl_fec.cpp,v 1.5 2004/08/03 06:35:56 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/****** Following two classes are private and only used by mcl_fec.cpp ******/ + +#if 0 +/** + * FEC encoding thread. + * Retrieve a job from the job list, perform FEC encoding, and put encoded + * packets on the transmission waiting queue + */ +void * +mcl_fec_thread::fec_thread (void *arg) +{ + mcl_cb *mclcb = (mcl_cb*)arg; + mcl_fec_job *job; + mcl_block *blk; + mcl_du *du; + INT32 i; + INT32 fec_created; + + TRACELVL(5, (mcl_stdout, "-> mcl_fec_thread::fec_thread:\n")) +#ifndef WIN32 + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + /* + * cancellation is deferred till next check point , i.e. points + * in code where we know everything is in a stable state + */ + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + while (1) { +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + while ((job = mclcb->fec.fec_job_list.dequeue()) == NULL) { + mcl_usleep(DFLT_POLLING_PERIOD); +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + + } + /* + * got a new job, now create the desired fec... + */ + blk = job->block; + TRACELVL(5, (mcl_stdout, + " mcl_fec_thread::fec_thread: create %d fec for blk %d/%d\n", + job->fec_desired, blk->adu->get_seq(), blk->seq)) + /* + * Produce FEC packets. + * XXX: a bit dangerous... + * Block object modified without being locked for this mclcb! + * This is required though to enable an asynchronous fec + * encoding... + * There is a risk if the session is destroyed in the meantime, + * or the adu free'ed... + */ + fec_created = mclcb->fec.fec_encoding_func(mclcb, blk, + job->first_fec_index, + job->fec_desired); +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + /* + * and now get the session lock... + */ + mclcb->lock(); + /* + * no longer pending. + * NB: decrement by fec_desired and not fec_created since + * no additional fec will be created for this job, even + * if fec_created < fec_desired... + */ + mclcb->fec.decr_pending_fec_creation_req(blk, job->fec_desired); + //if (blk->get_fec_du_nb_in_list() < job->fec_desired) + if (fec_created < job->fec_desired) { + /* failed, the encoder didn't produce the desired FEC */ + PRINT_ERR((mcl_stderr, + "mcl_fec_thread::fec_thread: ERROR, mcl_fec_encode failed: wanted %d, got %d\n", + job->fec_desired, fec_created)) +#ifdef DEBUG + mcl_exit(-1); +#endif + } + /* + * register each FEC packet created in the tx window. + * Must be done starting by the end of FEC list as FEC DUs + * may have already been produced. + */ + for (du = blk->get_fec_du_tail(), i = fec_created; + i > 0; i--, du = du->get_prev()) { + ASSERT(du); + mclcb->tx_window.register_new_du(mclcb, du); + } + mclcb->unlock(); +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + delete job; + } + TRACELVL(5, (mcl_stdout, "<- mcl_fec_thread::fec_thread:\n")) +} +#endif + + +/****** And this is the public class ******************************************/ + + +mcl_fec::mcl_fec () +{ + /* set everything to 0 */ + memset(this->max_k, 0, sizeof(this->max_k)); + memset(this->max_n, 0, sizeof(this->max_n)); + memset(this->cur_k, 0, sizeof(this->cur_k)); + memset(this->cur_n, 0, sizeof(this->cur_n)); + /* + * initialize the fec class for each supported FEC code. + * the order is significant since the last call specifies the + * default FEC code. + */ + this->initialize(MCL_FEC_SCHEME_NULL); +#ifdef RSE_FEC + this->initialize(MCL_FEC_SCHEME_RSE_129_0); +#endif + +} + + +mcl_fec::~mcl_fec () +{ +#ifdef DEBUG + memset(this->max_k, 0, sizeof(this->max_k)); + memset(this->max_n, 0, sizeof(this->max_n)); + memset(this->cur_k, 0, sizeof(this->cur_k)); + memset(this->cur_n, 0, sizeof(this->cur_n)); +#endif +} + + +/** + * Initializes the FEC class for a given FEC code. + * => See header file for more informations. + */ +void +mcl_fec::initialize (const INT32 new_code) +{ + switch (new_code) { +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + this->fec_codec = MCL_FEC_SCHEME_RSE_129_0; + ASSERT(RSE_MAX_K <= RSE_MAX_N); + ASSERT(RSE_MAX_N <= GF_SIZE); + this->max_k[MCL_FEC_SCHEME_RSE_129_0] = RSE_MAX_K; + this->max_n[MCL_FEC_SCHEME_RSE_129_0] = RSE_MAX_N; + this->cur_k[MCL_FEC_SCHEME_RSE_129_0] = RSE_DEFAULT_K; + this->cur_n[MCL_FEC_SCHEME_RSE_129_0] = RSE_DEFAULT_N; + // default: half data, half fec + break; +#endif + case MCL_FEC_SCHEME_NULL: + // no fec codec used, so use default conservative values... + this->fec_codec = MCL_FEC_SCHEME_NULL; + this->max_k[MCL_FEC_SCHEME_NULL] = 255; + this->max_n[MCL_FEC_SCHEME_NULL] = 255; + this->cur_k[MCL_FEC_SCHEME_NULL] = 255; + this->cur_n[MCL_FEC_SCHEME_NULL] = 255; + break; + default: + PRINT_ERR((mcl_stderr, + "mcl_fec::initialize: ERROR, called with unsupported FEC code %d\n", + new_code)) + mcl_exit(-1); + } +#if 0 + this->fec_ratio = this->cur_n[new_code] / this->cur_k[new_code]; + /* + * check it is coherent with the MAX_FEC_RATIO constant + * defined in mcl_profile.h + */ + if (this->fec_ratio > MAX_FEC_RATIO) { + PRINT_ERR((mcl_stderr, + "mcl_fec::initialize: ERROR, the calculated fec_ratio(%f) is larger than MAX_FEC_RATIO (%f) for code %d\nCheck and correct the various settings in mcl_profile.h accordingly...\n", + this->fec_ratio, MAX_FEC_RATIO, new_code)) + mcl_exit(-1); + } +#endif +} + + +/** + * Set the FEC code to be used. + * This function is sender specific (a receiver gets the FEC + * codec information info from the various incoming packet fields). + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::set_fec_code (mcl_cb *const mclcb, + const INT32 new_code) +{ + if (new_code == MCL_FEC_SCHEME_NULL) { + this->fec_codec = MCL_FEC_SCHEME_NULL; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use NO FEC\n")) + return MCL_OK; + } +#ifdef RSE_FEC + else if (new_code == MCL_FEC_SCHEME_RSE_129_0) { + this->fec_codec = MCL_FEC_SCHEME_RSE_129_0; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use RSE_129_0\n")) + return MCL_OK; + } +#endif + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_code: ERROR, code %d unknown\n", new_code)) + return MCL_ERROR; +} + + +#if 0 +/** + * Set the current FEC ratio, defined as n/k, and update cur_n. + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::set_fec_ratio (mcl_cb *const mclcb, + float new_fec_ratio) +{ + INT32 tmp_cur_n; + + if (new_fec_ratio < 1.0 || new_fec_ratio > MAX_FEC_RATIO) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, bad new_fec_ratio; got %f, should be in [1.0; %f]\n", new_fec_ratio, MAX_FEC_RATIO)) + goto bad; + } + tmp_cur_n = (INT32)((float)this->get_k() * new_fec_ratio); + if (tmp_cur_n > this->get_max_n()) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, new_fec_ratio %f too large, causes cur_n (%d) to be larger than max_n (%d)\n", + new_fec_ratio, tmp_cur_n, this->get_max_n())) + goto bad; + } + this->set_n(tmp_cur_n); + this->fec_ratio = new_fec_ratio; + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::set_fec_ratio: max_k/n=(%d; %d), cur_k/n=(%d; %d), fec_ratio=%f\n", + this->get_max_k(), this->get_max_n(), + this->get_k(), this->get_n(), this->fec_ratio)) + return MCL_OK; + +bad: + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, bad new_fec_ratio; got %f, should be in [1.0; 10.0]\n", new_fec_ratio)) + return MCL_ERROR; +} +#endif + +/** + * Set the current FEC ratio, defined as cur_n/cur_k, and update + * either cur_n or cur_k, depending on the FEC codec. + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::set_fec_ratio (mcl_cb *const mclcb, + float new_fec_ratio) +{ + + if (new_fec_ratio < 1.0) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, bad new_fec_ratio (%f), must be >= 1.0\n", new_fec_ratio)) + return MCL_ERROR; + } + switch (this->fec_codec) { + case MCL_FEC_SCHEME_NULL: + return (this->set_fec_ratio_from_n(mclcb, new_fec_ratio)); +#ifdef RSE_FEC + case MCL_FEC_SCHEME_RSE_129_0: + return (this->set_fec_ratio_from_n(mclcb, new_fec_ratio)); +#endif +#ifdef LDPC_FEC + case MCL_FEC_SCHEME_LDGM: + return (this->set_fec_ratio_from_k(mclcb, new_fec_ratio)); +#if 0 /* not yet! */ + case MCL_FEC_SCHEME_LDPC: + return (this->set_fec_ratio_from_k(mclcb, new_fec_ratio)); +#endif +#endif + default: + mcl_exit(-1); // impossible ! + return MCL_ERROR; // to avoid warning + } +} + + +mcl_error_status +mcl_fec::set_fec_ratio_from_n (mcl_cb *const mclcb, + float new_fec_ratio) +{ + INT32 tmp_cur_k; // used with CODE_NULL and RSE + + tmp_cur_k = (INT32)((float)this->get_n() / new_fec_ratio); + if (tmp_cur_k < 1) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio_from_n: ERROR, new_fec_ratio %f too large\n", new_fec_ratio)) + return MCL_ERROR; + } + this->set_k(tmp_cur_k); + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::set_fec_ratio_from_n: max_k/n=(%d; %d), cur_k/n=(%d; %d), ratio=%f\n", + this->get_max_k(), this->get_max_n(), + this->get_k(), this->get_n(), this->get_fec_ratio())) + return MCL_OK; +} + + +mcl_error_status +mcl_fec::set_fec_ratio_from_k (mcl_cb *const mclcb, + float new_fec_ratio) +{ + INT32 tmp_cur_n; // used with LDGM and LDPC + + tmp_cur_n = (INT32)((float)this->get_k() * new_fec_ratio); + if (tmp_cur_n > this->get_max_n()) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, new_fec_ratio %f too large, would causes the cur_n (%d) to be larger than max_n (%d)\n", + new_fec_ratio, tmp_cur_n, this->get_max_n())) + return MCL_ERROR; + } + this->set_n(tmp_cur_n); + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::set_fec_ratio_from_n: max_k/n=(%d; %d), cur_k/n=(%d; %d), ratio=%f\n", + this->get_max_k(), this->get_max_n(), + this->get_k(), this->get_n(), this->get_fec_ratio())) + return MCL_OK; +} + + +/** + * Return the number of available FEC packets (ie that have been + * created) that have not yet been sent. + */ +INT32 +mcl_fec::get_nb_fresh_fec_pkts (mcl_cb *const mclcb, + mcl_block *blk) +{ + return 0; // TODO, in the meantime assume everything has been sent +} + + +/** + * Return the number of FEC packets that can still be created for this + * block. + * Does NOT take into account the number of pending FEC creation requests. + */ +INT32 +mcl_fec::get_rem_nb_fec_pkts_to_create (mcl_cb *const mclcb, + mcl_block *blk) +{ + return (this->get_n() - blk->du_nb - blk->get_fec_du_nb_in_list()); +} + + +/** + * Encode the block and create the requested number of new FEC packets. + * Encoding is done asynchronously by the fec_thread + * and the results inserted automatically in the sender's + * transmission queue and in the block's FEC du list. + * @return < 0 if error, the number of FEC symbols created if ok + */ +INT32 +mcl_fec::encode (mcl_cb *const mclcb, + mcl_block *blk, + INT32 fec_desired) +{ + INT32 k; // effective k for this block + INT32 max_fec; // max nb of fec for this blk + INT32 start_index; // index of 1st FEC pkt to create + INT32 fec_to_create; + INT32 fec_created; // number of FEC pkts actually created + mcl_du *du; + INT32 i; + + TRACELVL(5, (mcl_stdout, + "-> mcl_fec::encode: blk seq=%d, want %d fec\n", + blk->seq, fec_desired)) + /* + * sanity checks... + */ + k = blk->du_nb; + ASSERT(k <= this->get_k()); + max_fec = get_rem_nb_fec_pkts_to_create(mclcb, blk); + if (fec_desired > max_fec || fec_desired <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_fec::encode: ERROR, illegal nb of FEC symbols desired (got %d, should be in ]0; %d]\n", + fec_desired, max_fec)) + return (-1); + } + /* do not consider the nb of pending fec creation requests */ + start_index = k + blk->get_fec_du_nb_in_list() + + this->get_pending_fec_creation_req(blk); + fec_to_create = fec_desired - this->get_pending_fec_creation_req(blk); + if (fec_to_create <= 0) { + TRACELVL(5, (mcl_stdout, "<- mcl_fec::encode: not required, enough pending FEC creations\n")) + return(0); + } + /* + * produce FEC packets... + */ + fec_created = mclcb->fec.fec_encoding_func(mclcb, blk, + start_index, + fec_to_create); + if (fec_created < fec_to_create) { + /* failed, the encoder didn't produce the desired FEC */ + PRINT_ERR((mcl_stderr, + "mcl_fec::encode: ERROR, mcl_fec_encode failed: wanted %d, got %d\n", + fec_to_create, fec_created)) +#ifdef DEBUG + mcl_exit(-1); +#endif + } + /* + * register each FEC packet created in the tx window. + * Must be done starting by the end of FEC list as FEC DUs + * may have already been produced. + */ + for (du = blk->get_fec_du_tail(), i = fec_created; + i > 0; i--, du = du->get_prev()) { + ASSERT(du); + mclcb->tx_window.register_new_du(mclcb, du); + } + + TRACELVL(5, (mcl_stdout, "<- mcl_fec::encode:\n")) + return fec_desired; +} + + +/** + * Performs FEC encoding for this block. + * This function may be called several times for the same block (even + * if calling it once may be faster), for instance to satisfy additional + * retransmission requests. + * @param blk block for which FEC packets must be created + * @param start_index index of the first (inclusive) FEC packet to create + * @param fec_desired number of FEC packets that must be created from + * start_index + * @returns number of FEC packets created if ok, < 0 if error. + */ +INT32 +mcl_fec::fec_encoding_func (mcl_cb *mclcb, + mcl_block *blk, + INT32 start_index, + INT32 fec_desired) +{ + INT32 k; /* k source DUs... */ + /* FEC DU seq nbs follow source DUs */ + INT32 n; /* total of n FEC+source DUs */ + UINT32 du_len; + UINT32 last_du_len; + INT32 i; + void *code; + mcl_du *fec_du; + char *fec_data; + char **src; + mcl_du *du; + + ASSERT(blk); + TRACELVL(5, (mcl_stdout, + "-> mcl_fec::fec_encoding_func: blk=%d, want %d fec\n", + blk->seq, fec_desired)) + k = blk->du_nb; + ASSERT(start_index >= k); + ASSERT(fec_desired > 0); + /* + * compute the size of a full-sized DU and of the last DU + * which may be shorter + */ + du_len = mclcb->get_payload_size(); + last_du_len = (k > 1) ? blk->len % du_len : blk->len; + if (last_du_len == 0) + last_du_len = du_len; /* multiple */ + /* + * create all the required FEC DUs for this block + */ + n = start_index + fec_desired; + ASSERT(n <= this->get_n()); + + if (!(code = fec_new(k,n))) { + goto no_memory; + } + /* + * no data copy except for the last du which may be shorter + */ + if (!(src = (char**)malloc(sizeof(char*) * n))) { + goto no_memory; + } + for (i = 0, du = blk->get_du_head(); i < k - 1; i++, du++) { + src[i] = (char*)(du->data); + } + if (!(src[k-1] = (char*)calloc(1, du_len))) { + goto no_memory; + } + ASSERT(du->seq == (UINT32)k-1); + ASSERT(du->len == last_du_len); + /* + * now create the n-k FEC DUs + */ + memcpy(src[k-1], du->data, last_du_len); + for (i = start_index; i < n; i++) { + if (!(fec_data = (char *) malloc(du_len))) { + goto no_memory; + } + fec_encode(code, (void**) src, fec_data, i, du_len); + fec_du = new mcl_du; + fec_du->block = blk; + fec_du->data = fec_data; + fec_du->seq = i; + fec_du->len = du_len; + fec_du->is_fec = true; + fec_du->pkt = NULL; // this is how a tx DU is distinguished + // from a rx DU! + fec_du->set_next(NULL); + fec_du->set_prev(NULL); + /* + * Use a linked list of FEC DUs rather than a single tab as + * with data DUs on the sending side! + */ + if (blk->insert_in_fec_du_list(mclcb, fec_du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_fec::fec_encoding_func: ERROR, insert_in_fec_du_list() failed\n")) +//#if 0 +printf("insert failed for fec_du seq=%d; start_idx=%d, fec_desired=%d\n", fec_du->seq, start_index, fec_desired); +int ii; +mcl_du *fdu; +for (ii=0, fdu = blk->get_fec_du_head(); iiget_fec_du_nb_in_list(); ii++, fdu = fdu->get_next()){ + printf("fec_du: seq=%d\n", fdu->seq); +} +//#endif + mcl_exit(-1); + } + TRACELVL(5, (mcl_stdout, + " mcl_fec::fec_encoding_func: created FEC seq=%d, len=%d, buf=x%x\n", + (INT32)fec_du->seq, (INT32)fec_du->len, + (INT32)fec_du->data)) + } + free(src[k-1]); + free(src); + fec_free(code); + TRACELVL(5, (mcl_stdout, "<- mcl_fec::fec_encoding_func: %d fec_du\n", + n - start_index)) + return (n - start_index); + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_fec::fec_encoding_func: ERROR, no memory\n")) + mcl_exit(-1); + return -1; // useless but avoids a warning +} + + +INT32 +mcl_fec::decode (mcl_cb *const mclcb, + mcl_block *blk) +{ + INT32 k; + INT32 n; + UINT32 du_len; /* full-sized DU length */ + UINT32 last_du_len; /* last DU (true) length */ + INT32 i; + u_char **dst; /* put rx data or fec here... */ + INT32 rx_index[GF_SIZE]; /* ... and their seq# here */ + UINT32 rem; /* remaining nb of DUs */ + void *code; + mcl_du *du; + UINT32 seq; /* next seq number expected */ +#ifdef DEBUG + char *data; /* data buffer */ +#endif + mcl_rx_pkt *pkt; /* used for data DUs created during decoding */ + u_char *buf; /* buffer where data/FEC DU data is copied */ + INT32 off; /* offset */ + + + ASSERT(blk); + TRACELVL(5, (mcl_stdout, "-> mcl_fec::decode: block seq=%d\n", blk->seq)) + /* make sure RSE is registered... required by some FEC functions + * like compute_n_for_this_block() */ + //this->set_fec_code (mclcb, MCL_FEC_SCHEME_RSE); + this->fec_codec = MCL_FEC_SCHEME_RSE_129_0; + /* + * check that FEC decode is indeed needed (i.e. that + * we need at least one FEC DU) + */ + k = blk->du_nb; + if (blk->get_du_nb_in_list() >= k) { + blk->set_rx_status(BLK_STATUS_DECODED); + TRACELVL(5, (mcl_stdout, + " mcl_fec::decode: decoding not needed\n")) + /*TRACELVL(5, ("decode: k=%d, du_in_list=%d, fec_in_list=%d\n", k, blk->get_du_nb_in_list(), blk->get_fec_du_nb_in_list()))*/ + goto free_fec_du; + } + /* + * compute the size of a full-sized DU and of the last DU + * which may be shorter + */ + du_len = mclcb->get_payload_size(); + last_du_len = (k > 1) ? blk->len % du_len : blk->len; + if (last_du_len == 0) + last_du_len = du_len; /* multiple */ + /* + * copy data and fec in dst buffer array first + * NB: this is required by the current FEC codec which modifies + * the dst buffers!!! + */ + if (!(dst = (u_char **) malloc(k * sizeof(u_char *)))) { + goto no_memory; + } + /* alloc a single large buf, where to copy all data/FEC DU data... */ + if (!(buf = (u_char *) malloc(k * du_len))) { + goto no_memory; + } + /* and remember the location of each DU buffer */ + for (i = 0, off = 0; i < k; i++, off += du_len) { + dst[i] = buf + off; + } + i = 0; /* index in rx_index[] */ + /* + * copy data DU to the dst array first + */ + for (rem = blk->get_du_nb_in_list(), du = blk->get_du_head(); + rem > 0; i++, rem--) { + ASSERT(du); + /* WARNING: if the following test failed, you probably forgot */ + /* to set the same tx_profile at the source AND receiver */ + if (du->len != du_len && du->len != last_du_len) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR: bad packet len (expected %d or %d, got %d)\nCheck transmission profiles at sender/receiver\n", + du_len, last_du_len, du->len)) + goto fatal_error; + } + if (i >= k) + break; /* security, eg. if there are more than k DUs */ + memcpy(dst[i], du->data, du->len); + if (du->len < du_len) { + /* non full-sized DU, so reset the remaining bytes */ + memset(dst[i] + du->len, 0, du_len - du->len); + } + rx_index[i] = du->seq; +#if 0 + PRINT_OUT((mcl_stdout, "decode: copy DATA du->seq=%d in dst[%d], rx_index[%d]=%d\n", + du->seq, i, i, rx_index[i])) +#endif + du = du->get_next(); + } + /* + * copy FEC DUs to the dst array now + */ + for (rem = blk->get_fec_du_nb_in_list(), du = blk->get_fec_du_head(); + rem > 0; i++, rem--, du = du->get_next()) { + ASSERT(du); + ASSERT(du->len == du_len); + if (i >= k) { + /* security, if there are more than k data+FEC DUs */ + break; + } + memcpy(dst[i], du->data, du->len); + /* rx_index[i] = du->seq + k; */ + rx_index[i] = du->seq; +#if 0 + PRINT_OUT((mcl_stdout, "decode: copy FEC du->seq=%d in dst[%d], rx_index[%d]=%d\n", + du->seq, i, i, rx_index[i])) +#endif + } + /* + * now decode + * NB: all the dst packets must be du_len long + */ + n = this->get_n(); + code = fec_new(k, n); + if (fec_decode(code, (void**)dst, rx_index, du_len)) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR, fec_decode failed\n")) + return -1; + } + fec_free(code); + + /* + * now update the block with the rx or reconstructed DUs + */ + for (rem = blk->du_nb, seq = 0, du = blk->get_du_head(); + rem > 0; rem--, seq++, du = du->get_next()) { + if (du && du->seq == seq) { + /* nothing to do, DU already received */ + continue; + } + /* + * else copy it from the FEC decoded matrix + */ + du = new mcl_du; + + du->block = blk; + du->seq = seq; + if (rem > 1) + du->len = du_len; + else + du->len = last_du_len; + du->is_fec = false; + du->set_next(NULL); + du->set_prev(NULL); + /* + * copy/store data now + */ + pkt = new mcl_rx_pkt (du->len); + pkt->pkt_len = du->len; + du->pkt = pkt; + du->data = pkt->get_buf(); + memcpy(du->data, dst[seq], du->len); + /* + * and insert it in the data DU list + */ + if (blk->insert_in_du_list(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR, insert_in_fec_du_list() failed\n")) + mcl_exit(-1); + } + TRACELVL(5, (mcl_stdout, + " decode: created DU seq=%d from dst[%d], len=%d, data buffer=x%x, du->data=x%x\n", + du->seq, seq, du->len, (int)data, (int)du->data)) +#if 0 + DumpBuffer(data, sizeof(char*) + du->len, (sizeof(char*) + du->len)>>2); +#endif + } + blk->set_rx_status(BLK_STATUS_DECODED); + + /* + * free the dst[] array and fec DU list now + */ + /* + * Warning: the fec_decode function can shuffle dst[] entries, so + * the new dst[0] entry may not point to buffer allocated previously! + */ + free(buf); + free(dst); +free_fec_du: + blk->remove_and_free_all_fec_dus(mclcb); + + TRACELVL(5, (mcl_stdout, "<- mcl_fec::decode: ok\n")) + return 0; + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR, no memory")) + mcl_exit(-1); + +fatal_error: + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR")) + mcl_exit(-1); + return -1; /* unreachable; avoid a compiler warning */ +} + diff --git a/src/norm/mcl_fec.cpp.org b/src/norm/mcl_fec.cpp.org new file mode 100644 index 0000000..0c3efa7 --- /dev/null +++ b/src/norm/mcl_fec.cpp.org @@ -0,0 +1,692 @@ +/* $Id: mcl_fec.cpp,v 1.3 2003/12/19 13:36:10 roca Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/****** Following two classes are private and only used by mcl_fec.cpp ******/ + +#if 0 +/** + * FEC encoding thread. + * Retrieve a job from the job list, perform FEC encoding, and put encoded + * packets on the transmission waiting queue + */ +void * +mcl_fec_thread::fec_thread (void *arg) +{ + mcl_cb *mclcb = (mcl_cb*)arg; + mcl_fec_job *job; + mcl_block *blk; + mcl_du *du; + INT32 i; + INT32 fec_created; + + TRACELVL(5, (mcl_stdout, "-> mcl_fec_thread::fec_thread:\n")) +#ifndef WIN32 + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + /* + * cancellation is deferred till next check point , i.e. points + * in code where we know everything is in a stable state + */ + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); +#endif + while (1) { +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + while ((job = mclcb->fec.fec_job_list.dequeue()) == NULL) { + mcl_usleep(DFLT_POLLING_PERIOD); +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + + } + /* + * got a new job, now create the desired fec... + */ + blk = job->block; + TRACELVL(5, (mcl_stdout, + " mcl_fec_thread::fec_thread: create %d fec for blk %d/%d\n", + job->fec_desired, blk->adu->get_seq(), blk->seq)) + /* + * Produce FEC packets. + * XXX: a bit dangerous... + * Block object modified without being locked for this mclcb! + * This is required though to enable an asynchronous fec + * encoding... + * There is a risk if the session is destroyed in the meantime, + * or the adu free'ed... + */ + fec_created = mclcb->fec.fec_encoding_func(mclcb, blk, + job->first_fec_index, + job->fec_desired); +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + /* + * and now get the session lock... + */ + mclcb->lock(); + /* + * no longer pending. + * NB: decrement by fec_desired and not fec_created since + * no additional fec will be created for this job, even + * if fec_created < fec_desired... + */ + mclcb->fec.decr_pending_fec_creation_req(blk, job->fec_desired); + //if (blk->get_fec_du_nb_in_list() < job->fec_desired) + if (fec_created < job->fec_desired) { + /* failed, the encoder didn't produce the desired FEC */ + PRINT_ERR((mcl_stderr, + "mcl_fec_thread::fec_thread: ERROR, mcl_fec_encode failed: wanted %d, got %d\n", + job->fec_desired, fec_created)) +#ifdef DEBUG + mcl_exit(-1); +#endif + } + /* + * register each FEC packet created in the tx window. + * Must be done starting by the end of FEC list as FEC DUs + * may have already been produced. + */ + for (du = blk->get_fec_du_tail(), i = fec_created; + i > 0; i--, du = du->get_prev()) { + ASSERT(du); + mclcb->tx_window.register_new_du(mclcb, du); + } + mclcb->unlock(); +#ifndef WIN32 + pthread_testcancel(); // check when thread has no lock +#endif + delete job; + } + TRACELVL(5, (mcl_stdout, "<- mcl_fec_thread::fec_thread:\n")) +} +#endif + + +/****** And this is the public class ******************************************/ + + +mcl_fec::mcl_fec () +{ + /* set everything to 0 */ + memset(this->max_k, 0, sizeof(this->max_k)); + memset(this->max_n, 0, sizeof(this->max_n)); + memset(this->cur_k, 0, sizeof(this->cur_k)); + memset(this->cur_n, 0, sizeof(this->cur_n)); + /* + * initialize the fec class for each supported FEC code. + * the order is significant since the last call specifies the + * default FEC code. + */ + this->initialize(MCL_FEC_CODE_NULL); +#ifdef RSE_FEC + this->initialize(MCL_FEC_CODE_RSE); +#endif + +} + + +mcl_fec::~mcl_fec () +{ +#ifdef DEBUG + memset(this->max_k, 0, sizeof(this->max_k)); + memset(this->max_n, 0, sizeof(this->max_n)); + memset(this->cur_k, 0, sizeof(this->cur_k)); + memset(this->cur_n, 0, sizeof(this->cur_n)); +#endif +} + + +/** + * Initializes the FEC class for a given FEC code. + * => See header file for more informations. + */ +void +mcl_fec::initialize (const INT32 new_code) +{ + switch (new_code) { +#ifdef RSE_FEC + case MCL_FEC_CODE_RSE: + this->fec_codec = MCL_FEC_CODE_RSE; + ASSERT(RSE_MAX_K <= RSE_MAX_N); + ASSERT(RSE_MAX_N <= GF_SIZE); + this->max_k[MCL_FEC_CODE_RSE] = RSE_MAX_K; + this->max_n[MCL_FEC_CODE_RSE] = RSE_MAX_N; + this->cur_k[MCL_FEC_CODE_RSE] = RSE_DEFAULT_K; + this->cur_n[MCL_FEC_CODE_RSE] = RSE_DEFAULT_N; + // default: half data, half fec + break; +#endif + case MCL_FEC_CODE_NULL: + // no fec codec used, so use default conservative values... + this->fec_codec = MCL_FEC_CODE_NULL; + this->max_k[MCL_FEC_CODE_NULL] = 255; + this->max_n[MCL_FEC_CODE_NULL] = 255; + this->cur_k[MCL_FEC_CODE_NULL] = 255; + this->cur_n[MCL_FEC_CODE_NULL] = 255; + break; + default: + PRINT_ERR((mcl_stderr, + "mcl_fec::initialize: ERROR, called with unsupported FEC code %d\n", + new_code)) + mcl_exit(-1); + } + this->fec_ratio = this->cur_n[new_code] / this->cur_k[new_code]; + /* + * check it is coherent with the MAX_FEC_RATIO constant + * defined in mcl_profile.h + */ + if (this->fec_ratio > MAX_FEC_RATIO) { + PRINT_ERR((mcl_stderr, + "mcl_fec::initialize: ERROR, the calculated fec_ratio(%f) is larger than MAX_FEC_RATIO (%f) for code %d\nCheck and correct the various settings in mcl_profile.h accordingly...\n", + this->fec_ratio, MAX_FEC_RATIO, new_code)) + mcl_exit(-1); + } +} + + +/** + * Set the FEC code to be used. + * This function is sender specific (a receiver gets the FEC + * codec information info from the various incoming packet fields). + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::set_fec_code (mcl_cb *const mclcb, + const INT32 new_code) +{ + if (new_code == MCL_FEC_CODE_NULL) { + this->fec_codec = MCL_FEC_CODE_NULL; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use NO FEC\n")) + return MCL_OK; + } +#ifdef RSE_FEC + else if (new_code == MCL_FEC_CODE_RSE) { + this->fec_codec = MCL_FEC_CODE_RSE; + ASSERT(get_max_k() > 0); /* must be true if initialized */ + TRACELVL(5, (mcl_stdout, " mcl_fec::set_fec_code: use RSE\n")) + return MCL_OK; + } +#endif + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_code: ERROR, code %d unknown\n", new_code)) + return MCL_ERROR; +} + + +/** + * Set the current FEC ratio, defined as n/k, and update cur_n. + * => See header file for more informations. + */ +mcl_error_status +mcl_fec::set_fec_ratio (mcl_cb *const mclcb, + float new_fec_ratio) +{ + INT32 tmp_cur_n; + + if (new_fec_ratio < 1.0 || new_fec_ratio > MAX_FEC_RATIO) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, bad new_fec_ratio; got %f, should be in [1.0; %f]\n", new_fec_ratio, MAX_FEC_RATIO)) + goto bad; + } + tmp_cur_n = (INT32)((float)this->get_k() * new_fec_ratio); + if (tmp_cur_n > this->get_max_n()) { + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, new_fec_ratio %f too large, causes cur_n (%d) to be larger than max_n (%d)\n", + new_fec_ratio, tmp_cur_n, this->get_max_n())) + goto bad; + } + this->set_n(tmp_cur_n); + this->fec_ratio = new_fec_ratio; + TRACELVL(5, (mcl_stdout, + "<- mcl_fec::set_fec_ratio: max_k/n=(%d; %d), cur_k/n=(%d; %d), fec_ratio=%f\n", + this->get_max_k(), this->get_max_n(), + this->get_k(), this->get_n(), this->fec_ratio)) + return MCL_OK; + +bad: + PRINT_ERR((mcl_stderr, + "mcl_fec::set_fec_ratio: ERROR, bad new_fec_ratio; got %f, should be in [1.0; 10.0]\n", new_fec_ratio)) + return MCL_ERROR; +} + + + +/** + * Return the number of available FEC packets (ie that have been + * created) that have not yet been sent. + */ +INT32 +mcl_fec::get_nb_fresh_fec_pkts (mcl_cb *const mclcb, + mcl_block *blk) +{ + return 0; // TODO, in the meantime assume everything has been sent +} + + +/** + * Return the number of FEC packets that can still be created for this + * block. + * Does NOT take into account the number of pending FEC creation requests. + */ +INT32 +mcl_fec::get_rem_nb_fec_pkts_to_create (mcl_cb *const mclcb, + mcl_block *blk) +{ + return (this->get_n() - blk->du_nb - blk->get_fec_du_nb_in_list()); +} + + +/** + * Encode the block and create the requested number of new FEC packets. + * Encoding is done asynchronously by the fec_thread + * and the results inserted automatically in the sender's + * transmission queue and in the block's FEC du list. + * @return < 0 if error, the number of FEC symbols created if ok + */ +INT32 +mcl_fec::encode (mcl_cb *const mclcb, + mcl_block *blk, + INT32 fec_desired) +{ + INT32 k; // effective k for this block + INT32 max_fec; // max nb of fec for this blk + INT32 start_index; // index of 1st FEC pkt to create + INT32 fec_to_create; + INT32 fec_created; // number of FEC pkts actually created + mcl_du *du; + INT32 i; + + TRACELVL(5, (mcl_stdout, + "-> mcl_fec::encode: blk seq=%d, want %d fec\n", + blk->seq, fec_desired)) + /* + * sanity checks... + */ + k = blk->du_nb; + ASSERT(k <= this->get_k()); + max_fec = get_rem_nb_fec_pkts_to_create(mclcb, blk); + if (fec_desired > max_fec || fec_desired <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_fec::encode: ERROR, illegal nb of FEC symbols desired (got %d, should be in ]0; %d]\n", + fec_desired, max_fec)) + return (-1); + } + /* do not consider the nb of pending fec creation requests */ + start_index = k + blk->get_fec_du_nb_in_list() + + this->get_pending_fec_creation_req(blk); + fec_to_create = fec_desired - this->get_pending_fec_creation_req(blk); + if (fec_to_create <= 0) { + TRACELVL(5, (mcl_stdout, "<- mcl_fec::encode: not required, enough pending FEC creations\n")) + return(0); + } + /* + * produce FEC packets... + */ + fec_created = mclcb->fec.fec_encoding_func(mclcb, blk, + start_index, + fec_to_create); + if (fec_created < fec_to_create) { + /* failed, the encoder didn't produce the desired FEC */ + PRINT_ERR((mcl_stderr, + "mcl_fec::encode: ERROR, mcl_fec_encode failed: wanted %d, got %d\n", + fec_to_create, fec_created)) +#ifdef DEBUG + mcl_exit(-1); +#endif + } + /* + * register each FEC packet created in the tx window. + * Must be done starting by the end of FEC list as FEC DUs + * may have already been produced. + */ + for (du = blk->get_fec_du_tail(), i = fec_created; + i > 0; i--, du = du->get_prev()) { + ASSERT(du); + mclcb->tx_window.register_new_du(mclcb, du); + } + + TRACELVL(5, (mcl_stdout, "<- mcl_fec::encode:\n")) + return fec_desired; +} + + +/** + * Performs FEC encoding for this block. + * This function may be called several times for the same block (even + * if calling it once may be faster), for instance to satisfy additional + * retransmission requests. + * @param blk block for which FEC packets must be created + * @param start_index index of the first (inclusive) FEC packet to create + * @param fec_desired number of FEC packets that must be created from + * start_index + * @returns number of FEC packets created if ok, < 0 if error. + */ +INT32 +mcl_fec::fec_encoding_func (mcl_cb *mclcb, + mcl_block *blk, + INT32 start_index, + INT32 fec_desired) +{ + INT32 k; /* k source DUs... */ + /* FEC DU seq nbs follow source DUs */ + INT32 n; /* total of n FEC+source DUs */ + UINT32 du_len; + UINT32 last_du_len; + INT32 i; + void *code; + mcl_du *fec_du; + char *fec_data; + char **src; + mcl_du *du; + + ASSERT(blk); + TRACELVL(5, (mcl_stdout, + "-> mcl_fec::fec_encoding_func: blk=%d, want %d fec\n", + blk->seq, fec_desired)) + k = blk->du_nb; + ASSERT(start_index >= k); + ASSERT(fec_desired > 0); + /* + * compute the size of a full-sized DU and of the last DU + * which may be shorter + */ + du_len = mclcb->get_payload_size(); + last_du_len = (k > 1) ? blk->len % du_len : blk->len; + if (last_du_len == 0) + last_du_len = du_len; /* multiple */ + /* + * create all the required FEC DUs for this block + */ + n = start_index + fec_desired; + ASSERT(n <= this->get_n()); + + if (!(code = fec_new(k,n))) { + goto no_memory; + } + /* + * no data copy except for the last du which may be shorter + */ + if (!(src = (char**)malloc(sizeof(char*) * n))) { + goto no_memory; + } + for (i = 0, du = blk->get_du_head(); i < k - 1; i++, du++) { + src[i] = (char*)(du->data); + } + if (!(src[k-1] = (char*)calloc(1, du_len))) { + goto no_memory; + } + ASSERT(du->seq == (UINT32)k-1); + ASSERT(du->len == last_du_len); + /* + * now create the n-k FEC DUs + */ + memcpy(src[k-1], du->data, last_du_len); + for (i = start_index; i < n; i++) { + if (!(fec_data = (char *) malloc(du_len))) { + goto no_memory; + } + fec_encode(code, (void**) src, fec_data, i, du_len); + fec_du = new mcl_du; + fec_du->block = blk; + fec_du->data = fec_data; + fec_du->seq = i; + fec_du->len = du_len; + fec_du->is_fec = true; + fec_du->pkt = NULL; // this is how a tx DU is distinguished + // from a rx DU! + fec_du->set_next(NULL); + fec_du->set_prev(NULL); + /* + * Use a linked list of FEC DUs rather than a single tab as + * with data DUs on the sending side! + */ + if (blk->insert_in_fec_du_list(mclcb, fec_du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_fec::fec_encoding_func: ERROR, insert_in_fec_du_list() failed\n")) +//#if 0 +printf("insert failed for fec_du seq=%d; start_idx=%d, fec_desired=%d\n", fec_du->seq, start_index, fec_desired); +int ii; +mcl_du *fdu; +for (ii=0, fdu = blk->get_fec_du_head(); iiget_fec_du_nb_in_list(); ii++, fdu = fdu->get_next()){ + printf("fec_du: seq=%d\n", fdu->seq); +} +//#endif + mcl_exit(-1); + } + TRACELVL(5, (mcl_stdout, + " mcl_fec::fec_encoding_func: created FEC seq=%d, len=%d, buf=x%x\n", + (INT32)fec_du->seq, (INT32)fec_du->len, + (INT32)fec_du->data)) + } + free(src[k-1]); + free(src); + fec_free(code); + TRACELVL(5, (mcl_stdout, "<- mcl_fec::fec_encoding_func: %d fec_du\n", + n - start_index)) + return (n - start_index); + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_fec::fec_encoding_func: ERROR, no memory\n")) + mcl_exit(-1); + return -1; // useless but avoids a warning +} + + +INT32 +mcl_fec::decode (mcl_cb *const mclcb, + mcl_block *blk) +{ + INT32 k; + INT32 n; + UINT32 du_len; /* full-sized DU length */ + UINT32 last_du_len; /* last DU (true) length */ + INT32 i; + u_char **dst; /* put rx data or fec here... */ + INT32 rx_index[GF_SIZE]; /* ... and their seq# here */ + UINT32 rem; /* remaining nb of DUs */ + void *code; + mcl_du *du; + UINT32 seq; /* next seq number expected */ +#ifdef DEBUG + char *data; /* data buffer */ +#endif + mcl_rx_pkt *pkt; /* used for data DUs created during decoding */ + u_char *buf; /* buffer where data/FEC DU data is copied */ + INT32 off; /* offset */ + + + ASSERT(blk); + TRACELVL(5, (mcl_stdout, "-> mcl_fec::decode: block seq=%d\n", blk->seq)) + /* make sure RSE is registered... required by some FEC functions + * like compute_n_for_this_block() */ + //this->set_fec_code (mclcb, MCL_FEC_CODE_LDGM); + this->fec_codec = MCL_FEC_CODE_LDGM; + /* + * check that FEC decode is indeed needed (i.e. that + * we need at least one FEC DU) + */ + k = blk->du_nb; + if (blk->get_du_nb_in_list() >= k) { + blk->set_rx_status(BLK_STATUS_DECODED); + TRACELVL(5, (mcl_stdout, + " mcl_fec::decode: decoding not needed\n")) + /*TRACELVL(5, ("decode: k=%d, du_in_list=%d, fec_in_list=%d\n", k, blk->get_du_nb_in_list(), blk->get_fec_du_nb_in_list()))*/ + goto free_fec_du; + } + /* + * compute the size of a full-sized DU and of the last DU + * which may be shorter + */ + du_len = mclcb->get_payload_size(); + last_du_len = (k > 1) ? blk->len % du_len : blk->len; + if (last_du_len == 0) + last_du_len = du_len; /* multiple */ + /* + * copy data and fec in dst buffer array first + * NB: this is required by the current FEC codec which modifies + * the dst buffers!!! + */ + if (!(dst = (u_char **) malloc(k * sizeof(u_char *)))) { + goto no_memory; + } + /* alloc a single large buf, where to copy all data/FEC DU data... */ + if (!(buf = (u_char *) malloc(k * du_len))) { + goto no_memory; + } + /* and remember the location of each DU buffer */ + for (i = 0, off = 0; i < k; i++, off += du_len) { + dst[i] = buf + off; + } + i = 0; /* index in rx_index[] */ + /* + * copy data DU to the dst array first + */ + for (rem = blk->get_du_nb_in_list(), du = blk->get_du_head(); + rem > 0; i++, rem--) { + ASSERT(du); + /* WARNING: if the following test failed, you probably forgot */ + /* to set the same tx_profile at the source AND receiver */ + if (du->len != du_len && du->len != last_du_len) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR: bad packet len (expected %d or %d, got %d)\nCheck transmission profiles at sender/receiver\n", + du_len, last_du_len, du->len)) + goto fatal_error; + } + if (i >= k) + break; /* security, eg. if there are more than k DUs */ + memcpy(dst[i], du->data, du->len); + if (du->len < du_len) { + /* non full-sized DU, so reset the remaining bytes */ + memset(dst[i] + du->len, 0, du_len - du->len); + } + rx_index[i] = du->seq; +#if 0 + PRINT_OUT((mcl_stdout, "decode: copy DATA du->seq=%d in dst[%d], rx_index[%d]=%d\n", + du->seq, i, i, rx_index[i])) +#endif + du = du->get_next(); + } + /* + * copy FEC DUs to the dst array now + */ + for (rem = blk->get_fec_du_nb_in_list(), du = blk->get_fec_du_head(); + rem > 0; i++, rem--, du = du->get_next()) { + ASSERT(du); + ASSERT(du->len == du_len); + if (i >= k) { + /* security, if there are more than k data+FEC DUs */ + break; + } + memcpy(dst[i], du->data, du->len); + /* rx_index[i] = du->seq + k; */ + rx_index[i] = du->seq; +#if 0 + PRINT_OUT((mcl_stdout, "decode: copy FEC du->seq=%d in dst[%d], rx_index[%d]=%d\n", + du->seq, i, i, rx_index[i])) +#endif + } + /* + * now decode + * NB: all the dst packets must be du_len long + */ + n = this->get_n(); + code = fec_new(k, n); + if (fec_decode(code, (void**)dst, rx_index, du_len)) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR, fec_decode failed\n")) + return -1; + } + fec_free(code); + + /* + * now update the block with the rx or reconstructed DUs + */ + for (rem = blk->du_nb, seq = 0, du = blk->get_du_head(); + rem > 0; rem--, seq++, du = du->get_next()) { + if (du && du->seq == seq) { + /* nothing to do, DU already received */ + continue; + } + /* + * else copy it from the FEC decoded matrix + */ + du = new mcl_du; + + du->block = blk; + du->seq = seq; + if (rem > 1) + du->len = du_len; + else + du->len = last_du_len; + du->is_fec = false; + du->set_next(NULL); + du->set_prev(NULL); + /* + * copy/store data now + */ + pkt = new mcl_rx_pkt (du->len); + pkt->pkt_len = du->len; + du->pkt = pkt; + du->data = pkt->get_buf(); + memcpy(du->data, dst[seq], du->len); + /* + * and insert it in the data DU list + */ + if (blk->insert_in_du_list(mclcb, du) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR, insert_in_fec_du_list() failed\n")) + mcl_exit(-1); + } + TRACELVL(5, (mcl_stdout, + " decode: created DU seq=%d from dst[%d], len=%d, data buffer=x%x, du->data=x%x\n", + du->seq, seq, du->len, (int)data, (int)du->data)) +#if 0 + DumpBuffer(data, sizeof(char*) + du->len, (sizeof(char*) + du->len)>>2); +#endif + } + blk->set_rx_status(BLK_STATUS_DECODED); + + /* + * free the dst[] array and fec DU list now + */ + /* + * Warning: the fec_decode function can shuffle dst[] entries, so + * the new dst[0] entry may not point to buffer allocated previously! + */ + free(buf); + free(dst); +free_fec_du: + blk->remove_and_free_all_fec_dus(mclcb); + + TRACELVL(5, (mcl_stdout, "<- mcl_fec::decode: ok\n")) + return 0; + +no_memory: + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR, no memory")) + mcl_exit(-1); + +fatal_error: + PRINT_ERR((mcl_stderr, "mcl_fec::decode: ERROR")) + mcl_exit(-1); + return -1; /* unreachable; avoid a compiler warning */ +} + diff --git a/src/norm/mcl_fec.h b/src/norm/mcl_fec.h new file mode 100644 index 0000000..0f08a8b --- /dev/null +++ b/src/norm/mcl_fec.h @@ -0,0 +1,363 @@ +/* $Id: mcl_fec.h,v 1.5 2004/08/03 06:35:56 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_FEC_H +#define MCL_FEC_H + +/* + * Simplified synchronous FEC class. + * Encoding is performed in the current thread rather than in a dedicated + * thread (see mcl_async_thread.h/cpp). + */ + + +/** + * Main FEC class. + */ +class mcl_fec { +friend class mcl_fec_thread; // required for fec_thread to access + // fec_encoding_func() and fec_job_list + +public: + /****** Public Members ************************************************/ + mcl_fec (); + ~mcl_fec (); + + /** + * Initializes the FEC class for a given FEC code. + * Replaces the default constructor. + * @param new_code FEC code to use. Can be one of + * MCL_FEC_SCHEME_NULL, ...RSE, ...LDGM, ...LDPC. + * (see mcl_lib_api_alc.h). Default is NULL. + */ + void initialize (const INT32 new_code = 0); + + /** + * Return the maximum block size (in number of DUs). + * This parameter is set at mcl_fec service initialization + * depending on the FEC code used, and is READ-ONLY. + * We have: max_k <= max_n (no FEC DU if equal). + * @return maximum k. + */ + INT32 get_max_k () const; + + /** + * Return the maximum n value for a block (in number of DUs). + * This parameter is set at mcl_fec service initialization + * depending on the FEC code used, and is READ-ONLY. + * @return maximum n. + */ + INT32 get_max_n () const; + + /** + * Set the effective block size to use (in number of DUs). + * 0 < k <= max_k made possible by the code. + * If k == n, then no FEC DU will be produced. + * @param k new k value. + */ + void set_k (const INT32 k); + + /** + * Return the effective block size used currently (in number of DUs). + * @return effective k value to use. + */ + INT32 get_k (void) const; + + /** + * Set the effective n value to use (in number of DUs). + * 0 < n <= max_n made possible by the code. + * If k == n, then no FEC DU will be produced. + * @param n new n value to use. + */ + void set_n (const INT32 n); + + /** + * Return the effective n parameter used currently (in number of DUs). + * @return effective n value. + */ + INT32 get_n (void) const; + + /** + * Set the FEC code to be used. + * This function is sender specific (a receiver gets the FEC + * codec information info from the various incoming packet fields). + * This function only changes the FEC code to use from now on, + * without modifying anything else. It assumes that the FEC + * codec specific parameters have already been initialized. + * @param new_code FEC code to use from now on... + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_fec_code (class mcl_cb *const mclcb, + const INT32 new_code); + + /** + * Set the current FEC ratio, defined as cur_n/cur_k, and update + * either cur_n or cur_k, depending on the FEC codec. + * Note that this ratio only applies to the current FEC codec, not + * to others, so set the FEC codec first before setting the FEC ratio! + * With RSE, from the cur_n value, it defines the new cur_k value, + * and checks it is reasonable (e.g. >= 1). + * With LDPC, from the cur_k value, it defines the new cur_n value, + * and checks it is compatible with the max_n value. + * This is required by the fact that the n parameter is not carried + * by the EXT_FTI associated to FEC encoding ID 128 and 130 (i.e. + * used by NULL and RSE), unlike our private FEC encoding ID 140! + * It means that the appropriate FEC ratio must be set by both the + * sender AND receiver with FEC encoding IDs 128 and 130, but only + * at the sender with our FEC encoding ID 140. + * The above settings for cur_k and cur_n are only valid for blocks + * of maximum size. Otherwise, with smalle blocks, the n value + * associated to k < cur_k is calculated from the cur_n/cur_k ratio. + * + * @param mclcb + * @param new_fec_ratio desired FEC ratio + * @return Completion status (MCL_OK or MCL_ERROR). + * If the new n or k value is invalid, then + * an error is returned. + */ + + mcl_error_status set_fec_ratio (mcl_cb *const mclcb, + float new_fec_ratio); + + /** + * Return the current FEC ratio, defined as n/k. + */ + float get_fec_ratio () const; + + /** + * Return the number of available FEC packets (ie that have been + * created) that have not yet been sent. + */ + INT32 get_nb_fresh_fec_pkts (mcl_cb *const mclcb, + mcl_block *blk); + + /** + * Return the number of FEC packets that can still be created for this + * block. + * Does NOT take into account the number of pending FEC creation + * requests. + */ + INT32 get_rem_nb_fec_pkts_to_create (mcl_cb *const mclcb, + mcl_block *blk); + + /** + * Return the number of pending FEC creation requests for this block. + * This is the sum of packets to create over all pending FEC jobs for + * this block. + * @param blk block concerned + * @return number of FEC packets that are to be created + */ + INT32 get_pending_fec_creation_req (mcl_block *blk); + + /** + * Increments the number of pending FEC creation requests for this + * block. + * Used after the creation of a FEC job. + * @param blk block concerned + * @param fec_to_create + */ + void incr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_to_create); + + /** + * Decrements the number of pending FEC creation requests for this + * block. + * Used after the completion of a FEC job. + * @param blk block concerned + * @param fec_created + */ + void decr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_created); + + /** + * Encode the block and create the requested number of new FEC packets. + * Encoding is done asynchronously by the fec_encoding_thread + * and the results inserted automatically in the sender's + * transmission queue. + * @param mclcb + * @param blk block for which FEC packets must be created + * @param fec_desired number of FEC packets that must be created + * @return < 0 if error, the number of FEC symbols created if ok + */ + INT32 encode (mcl_cb *const mclcb, + mcl_block *blk, + INT32 fec_desired); + + /** + * Decode the block. + * Decoding is done immediately. + * @return < 0 if error, the number of FEC symbols created if ok + */ + INT32 decode (mcl_cb *const mclcb, + mcl_block *blk); + + + /** + * Return the thread id. + * Required to enable a safe thread destruction. + */ + mcl_thread_t get_fec_encoding_thread_id (); + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + /** + * Set the current FEC ratio, defined as cur_n/cur_k, from n, and + * update cur_k. + * @param mclcb + * @param new_fec_ratio desired FEC ratio + * @return Completion status (MCL_OK or MCL_ERROR). + * If the new k value is invalid, then + * an error is returned. + */ + mcl_error_status set_fec_ratio_from_n (mcl_cb *const mclcb, + float new_fec_ratio); + + /** + * Set the current FEC ratio, defined as cur_n/cur_k, from k, and + * update cur_n. + * @param mclcb + * @param new_fec_ratio desired FEC ratio + * @return Completion status (MCL_OK or MCL_ERROR). + * If the new n value is invalid, then + * an error is returned. + */ + mcl_error_status set_fec_ratio_from_k (mcl_cb *const mclcb, + float new_fec_ratio); + + /** + * Performs FEC encoding for this block. + * This function may be called several times for the same block (even + * if calling it once may be faster), for instance to satisfy + * additional retransmission requests. + * @param blk block for which FEC packets must be created + * @param start_index index of the first (inclusive) FEC packet + * to create + * @param fec_desired number of FEC packets that must be created + * from start_index + * @returns number of FEC packets created if ok, < 0 if error. + */ + INT32 fec_encoding_func (mcl_cb *const mclcb, + mcl_block *blk, + INT32 start_index, + INT32 fec_desired); + + + /****** Private Attributes ********************************************/ + + INT32 fec_codec; /** + * Codec to use for this session. + * Can be one of MCL_FEC_SCHEME_NULL, ...RSE, + * ...LDGM, ...LDPC. + */ + + /* max_X are _statically_ defined, at initialization */ + INT32 max_k[MCL_FEC_SCHEME_NB]; /** Max k value. FEC dependant */ + INT32 max_n[MCL_FEC_SCHEME_NB]; /** Max n value. FEC dependant */ + /* cur_X are initialized with default values, but they can be + * overriden latter on by the user */ + INT32 cur_k[MCL_FEC_SCHEME_NB]; /** k value currently in use. */ + INT32 cur_n[MCL_FEC_SCHEME_NB]; /** n value currently in use. */ + +#if 0 + /* fec_ratio is initialized with a default value, but it can be + * overriden latter on by the user */ + float fec_ratio; /** Current FEC ratio defined as n/k. */ +#endif +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline INT32 +mcl_fec::get_max_k () const +{ + return this->max_k[this->fec_codec]; +} + +inline INT32 +mcl_fec::get_max_n () const +{ + return this->max_n[this->fec_codec]; +} + +inline INT32 +mcl_fec::get_k (void) const +{ + return this->cur_k[this->fec_codec]; +} + +inline void +mcl_fec::set_k (const INT32 k) +{ + ASSERT(k <= max_k[this->fec_codec]); + ASSERT(k > 0); + ASSERT(k <= cur_n[this->fec_codec]); + this->cur_k[this->fec_codec] = k; +} + +inline INT32 +mcl_fec::get_n () const +{ + return this->cur_n[this->fec_codec]; +} + +inline void +mcl_fec::set_n (const INT32 n) +{ + ASSERT(n <= max_n[this->fec_codec]); + ASSERT(n > 0); + ASSERT(cur_k[this->fec_codec] <= n); + this->cur_n[this->fec_codec] = n; +} + +inline float +mcl_fec::get_fec_ratio () const +{ + return ((double)this->get_n() / (double)this->get_k()); +} + +inline INT32 +mcl_fec::get_pending_fec_creation_req (mcl_block *blk) +{ + return (blk->pending_fec_creation_req); +} + +inline void +mcl_fec::incr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_to_create) +{ + blk->pending_fec_creation_req += fec_to_create; +} + +inline void +mcl_fec::decr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_created) +{ + blk->pending_fec_creation_req -= fec_created; +} + +#endif // MCL_FEC_H + diff --git a/src/norm/mcl_fec.h.org b/src/norm/mcl_fec.h.org new file mode 100644 index 0000000..e1fc3a3 --- /dev/null +++ b/src/norm/mcl_fec.h.org @@ -0,0 +1,324 @@ +/* $Id: mcl_fec.h,v 1.3 2003/12/19 13:36:10 roca Exp $ */ +/* + * Copyright (c) 2003 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_FEC_H +#define MCL_FEC_H + +/* + * Simplified synchronous FEC class. + * Encoding is performed in the current thread rather than in a dedicated + * thread (see mcl_async_thread.h/cpp). + */ + + +/** + * Main FEC class. + */ +class mcl_fec { +friend class mcl_fec_thread; // required for fec_thread to access + // fec_encoding_func() and fec_job_list + +public: + /****** Public Members ************************************************/ + mcl_fec (); + ~mcl_fec (); + + /** + * Initializes the FEC class for a given FEC code. + * Replaces the default constructor. + * @param new_code FEC code to use. Can be one of + * MCL_FEC_CODE_NULL, ...RSE, ...LDGM, ...LDPC. + * (see mcl_lib_api_alc.h). Default is NULL. + */ + void initialize (const INT32 new_code = 0); + + /** + * Return the maximum block size (in number of DUs). + * This parameter is set at mcl_fec service initialization + * depending on the FEC code used, and is READ-ONLY. + * We have: max_k <= max_n (no FEC DU if equal). + * @return maximum k. + */ + INT32 get_max_k () const; + + /** + * Return the maximum n value for a block (in number of DUs). + * This parameter is set at mcl_fec service initialization + * depending on the FEC code used, and is READ-ONLY. + * @return maximum n. + */ + INT32 get_max_n () const; + + /** + * Set the effective block size to use (in number of DUs). + * 0 < k <= max_k made possible by the code. + * If k == n, then no FEC DU will be produced. + * @param k new k value. + */ + void set_k (const INT32 k); + + /** + * Return the effective block size used currently (in number of DUs). + * @return effective k value to use. + */ + INT32 get_k (void) const; + + /** + * Set the effective n value to use (in number of DUs). + * 0 < n <= max_n made possible by the code. + * If k == n, then no FEC DU will be produced. + * @param n new n value to use. + */ + void set_n (const INT32 n); + + /** + * Return the effective n parameter used currently (in number of DUs). + * @return effective n value. + */ + INT32 get_n (void) const; + + /** + * Set the FEC code to be used. + * This function is sender specific (a receiver gets the FEC + * codec information info from the various incoming packet fields). + * This function only changes the FEC code to use from now on, + * without modifying anything else. It assumes that the FEC + * codec specific parameters have already been initialized. + * @param new_code FEC code to use from now on... + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_fec_code (class mcl_cb *const mclcb, + const INT32 new_code); + + /** + * Set the current FEC ratio, defined as n/k, and update cur_n. + * From the cur_k value, it defines the new cur_n value, and + * check it is compatible with the max_n value. It also checks + * that the FEC ratio is compatible with the max fec_ratio value. + * @param mclcb + * @param new_fec_ratio desired FEC ratio + * @return Completion status (MCL_OK or MCL_ERROR). + * If the new n value is larger than max_n, or + * if the desidered fec_ratio is larger than + * the statically defined maximum fec_ratio, then + * an error is returned. + */ + mcl_error_status set_fec_ratio (mcl_cb *const mclcb, + float new_fec_ratio); + + /** + * Return the current FEC ratio, defined as n/k. + */ + float get_fec_ratio () const; + + /** + * Return the number of available FEC packets (ie that have been + * created) that have not yet been sent. + */ + INT32 get_nb_fresh_fec_pkts (mcl_cb *const mclcb, + mcl_block *blk); + + /** + * Return the number of FEC packets that can still be created for this + * block. + * Does NOT take into account the number of pending FEC creation + * requests. + */ + INT32 get_rem_nb_fec_pkts_to_create (mcl_cb *const mclcb, + mcl_block *blk); + + /** + * Return the number of pending FEC creation requests for this block. + * This is the sum of packets to create over all pending FEC jobs for + * this block. + * @param blk block concerned + * @return number of FEC packets that are to be created + */ + INT32 get_pending_fec_creation_req (mcl_block *blk); + + /** + * Increments the number of pending FEC creation requests for this + * block. + * Used after the creation of a FEC job. + * @param blk block concerned + * @param fec_to_create + */ + void incr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_to_create); + + /** + * Decrements the number of pending FEC creation requests for this + * block. + * Used after the completion of a FEC job. + * @param blk block concerned + * @param fec_created + */ + void decr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_created); + + /** + * Encode the block and create the requested number of new FEC packets. + * Encoding is done asynchronously by the fec_encoding_thread + * and the results inserted automatically in the sender's + * transmission queue. + * @param mclcb + * @param blk block for which FEC packets must be created + * @param fec_desired number of FEC packets that must be created + * @return < 0 if error, the number of FEC symbols created if ok + */ + INT32 encode (mcl_cb *const mclcb, + mcl_block *blk, + INT32 fec_desired); + + /** + * Decode the block. + * Decoding is done immediately. + * @return < 0 if error, the number of FEC symbols created if ok + */ + INT32 decode (mcl_cb *const mclcb, + mcl_block *blk); + + + /** + * Return the thread id. + * Required to enable a safe thread destruction. + */ + mcl_thread_t get_fec_encoding_thread_id (); + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + /** + * Performs FEC encoding for this block. + * This function may be called several times for the same block (even + * if calling it once may be faster), for instance to satisfy + * additional retransmission requests. + * @param blk block for which FEC packets must be created + * @param start_index index of the first (inclusive) FEC packet + * to create + * @param fec_desired number of FEC packets that must be created + * from start_index + * @returns number of FEC packets created if ok, < 0 if error. + */ + INT32 fec_encoding_func (mcl_cb *const mclcb, + mcl_block *blk, + INT32 start_index, + INT32 fec_desired); + + + /****** Private Attributes ********************************************/ + + INT32 fec_codec; /** + * Codec to use for this session. + * Can be one of MCL_FEC_CODE_NULL, ...RSE, + * ...LDGM, ...LDPC. + */ + + /* max_X are _statically_ defined, at initialization */ + INT32 max_k[MCL_FEC_CODE_MAX_NB]; /** Max k value. FEC dependant */ + INT32 max_n[MCL_FEC_CODE_MAX_NB]; /** Max n value. FEC dependant */ + /* cur_X are initialized with default values, but they can be + * overriden latter on by the user */ + INT32 cur_k[MCL_FEC_CODE_MAX_NB]; /** k value currently in use. */ + INT32 cur_n[MCL_FEC_CODE_MAX_NB]; /** n value currently in use. */ + + /* fec_ratio is initialized with a default value, but it can be + * overriden latter on by the user */ + float fec_ratio; /** Current FEC ratio defined as n/k. */ +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline INT32 +mcl_fec::get_max_k () const +{ + return this->max_k[this->fec_codec]; +} + +inline INT32 +mcl_fec::get_max_n () const +{ + return this->max_n[this->fec_codec]; +} + +inline INT32 +mcl_fec::get_k (void) const +{ + return this->cur_k[this->fec_codec]; +} + +inline void +mcl_fec::set_k (const INT32 k) +{ + ASSERT(k <= max_k[this->fec_codec]); + ASSERT(k > 0); + ASSERT(k <= cur_n[this->fec_codec]); + this->cur_k[this->fec_codec] = k; +} + +inline INT32 +mcl_fec::get_n () const +{ + return this->cur_n[this->fec_codec]; +} + +inline void +mcl_fec::set_n (const INT32 n) +{ + ASSERT(n <= max_n[this->fec_codec]); + ASSERT(n > 0); + ASSERT(cur_k[this->fec_codec] <= n); + this->cur_n[this->fec_codec] = n; +} + +inline float +mcl_fec::get_fec_ratio () const +{ + return this->fec_ratio; +} + +inline INT32 +mcl_fec::get_pending_fec_creation_req (mcl_block *blk) +{ + return (blk->pending_fec_creation_req); +} + +inline void +mcl_fec::incr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_to_create) +{ + blk->pending_fec_creation_req += fec_to_create; +} + +inline void +mcl_fec::decr_pending_fec_creation_req (mcl_block *blk, + INT32 fec_created) +{ + blk->pending_fec_creation_req -= fec_created; +} + +#endif // MCL_FEC_H + diff --git a/src/norm/mcl_fsm.cpp b/src/norm/mcl_fsm.cpp new file mode 100644 index 0000000..738ace8 --- /dev/null +++ b/src/norm/mcl_fsm.cpp @@ -0,0 +1,395 @@ +/* $Id: mcl_fsm.cpp,v 1.3 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/* + * SENDER's FSM (Finite State Machine) + * + * NIL + * | + * | appli issues mcl_open() + * mcl_abort() v appli issues mcl_close() + * +----------- READY --------------------------------------------+ + * | | | + * | | first ADU submission | + * | v | + * | IN_TX : send NEW_ADU; send DU | + * | | | | ^ | + * | | | | | continue to tx or wait new ADU | + * +------------+ | +-----+ | + * | | | + * | | appli issues mcl_close() and is blocked | + * | v | + * | FINISH_TO_TX : send NO_NEW_ADU; send DU | + * | | | | ^ | + * | | | | | there are remaining DUs | + * +------------+ | +-----+ or pending ctrl operations | + * | | | + * | | all DUs have been tx & no pending ctrl | + * | | | + * +------------+ | +---------------------------------------------+ + * | | | + * v v v + * END : send CLOSE + * | + * | nothing else to do + * v + * CLOSED : mcl_close() returns + * | + * v + * NIL + */ + +/* + * SENDER's FSM (Finite State Machine) transition table + */ +#define xx TSTATE_INVALID /* for clarity */ +static const mcl_tx_states next_tx_state[6/*state*/][9/*event*/] = { + /* NIL OPEN_CALLED NEW_ADU ALL_DU_SENT CLOSE_CALLED CLOSE_SENT CLOSE_RETURN ABORT RESET*/ + /* NIL */ {xx, TSTATE_READY, xx, xx, xx, xx, xx, xx, xx}, + /* READY */ {xx, xx, TSTATE_IN_TX, xx, TSTATE_END, xx, xx, TSTATE_END, TSTATE_READY}, + /* IN_TX */ {xx, xx, TSTATE_IN_TX, xx, TSTATE_FINISH_TX,xx, xx, TSTATE_END, TSTATE_READY}, +/* FINISH_TX*/ {xx, xx, xx, TSTATE_END, xx, xx, xx, TSTATE_END, TSTATE_READY}, + /* END */ {xx, xx, xx, xx, xx, TSTATE_CLOSED, xx, TSTATE_END, TSTATE_READY}, + /* CLOSED */ {xx, xx, xx, xx, xx, xx, TSTATE_NIL, TSTATE_NIL, xx} +}; +#undef xx + + +/* + * RECEIVER's FSM (Finite State Machine) + * + * NIL + * | + * | appli issues mcl_open() + * v + * READY + * | | | + * +----+ | +-------------------------------+ + * recv | | | appli calls + * CLOSE | | first NEW_ADU received | mcl_close() + * | v | or + * | IN_RX : | mcl_abort() + * | | | | | ^ | + * | | | | | | recv NEW_ADU; recv DU | + * +---+ | | +-----+ | + * recv | | +--------------------------------+ + * CLOSE | | | appli calls + * | | recv NO_NEW_ADU from peer | mcl_close() + * | v | or + * | FINISH_RX : | mcl_abort() + * | | | | | ^ | + * | | | | | | recv DU | + * +----+ | | +-----+ | + * recv | | +-------------------------------+ + * CLOSE | | | appli calls + * | | all DUs have been received | mcl_close() + * | v | or + * | END : | mcl_abort() + * | | | | ^ | + * | | | | | recv DU (ignored) | + * recv +-----+ | +-----+ | + * CLOSE | | | + * | | | + * v | | + * CLOSE_RX | | + * | | | + * +-------+--------------------------------+ + * | appli calls mcl_close() + * | + * v + * CLOSED : mcl_close() returns + * | + * v + * NIL + * + * State END: + * we have received everything and the sender will not send any new ADU + * we may still receive (duplicated) DUs but we can stop at any time + * this is the normal (almost) final state when everything is ok + */ + +/* + * RECEIVER's FSM (Finite State Machine) transition table + */ +#define xx RSTATE_INVALID /* for clarity */ +static const mcl_rx_states next_rx_state[7/*state*/][9/*event*/] = { + /* NIL, OPEN_CALLED NEW_ADU NO_NEW_ADU DU_RECV ALL_DU_RECV CLOSE_CALLED CLOSE_RECV CLOSE_RETURN*/ + /* NIL */ {xx, RSTATE_READY, xx, xx, xx, xx, xx, xx, xx}, + /* READY */ {xx, xx, RSTATE_IN_RX, xx, xx, xx, RSTATE_CLOSED, RSTATE_CLOSE_RX,xx}, + /* IN_RX */ {xx, xx, RSTATE_IN_RX, RSTATE_FINISH_RX,RSTATE_IN_RX, xx, RSTATE_CLOSED, RSTATE_CLOSE_RX,xx}, +/* FINISH_RX*/ {xx, xx, xx, RSTATE_FINISH_RX,RSTATE_FINISH_RX,RSTATE_END, RSTATE_CLOSED, RSTATE_CLOSE_RX,xx}, + /* END */ {xx, xx, xx, RSTATE_END, RSTATE_END, xx, RSTATE_CLOSED, RSTATE_CLOSE_RX,xx}, + /*CLOSE_RX*/ {xx, xx, xx, xx, xx, xx, RSTATE_CLOSED, RSTATE_CLOSE_RX, RSTATE_NIL}, + /* CLOSED */ {xx, xx, xx, xx, xx, xx, xx, RSTATE_CLOSED, RSTATE_NIL} +}; +#undef xx + + +/* + * strings for debug + */ +static const char * tx_states_msg[] = { + "TSTATE_NIL", + "TSTATE_READY", + "TSTATE_IN_TX", + "TSTATE_FINISH_TX", + "TSTATE_END", + "TSTATE_CLOSED", + "*INVALID TSTATE*" +}; +static const char * tx_events_msg[] = { + "TEVENT_NIL", + "TEVENT_OPEN_CALLED", + "TEVENT_NEW_ADU", + "TEVENT_ALL_DU_SENT", + "TEVENT_CLOSE_CALLED", + "TEVENT_CLOSE_SENT", + "TEVENT_CLOSE_RETURN", + "TEVENT_ABORT", + "TEVENT_RESET" +}; +static const char * rx_states_msg[] = { + "RSTATE_NIL", + "RSTATE_READY", + "RSTATE_IN_RX", + "RSTATE_FINISH_RX", + "RSTATE_END", + "RSTATE_CLOSE_RX", + "RSTATE_CLOSED", + "*INVALID RSTATE*" +}; +static const char * rx_events_msg[] = { + "REVENT_NIL", + "REVENT_OPEN_CALLED", + "REVENT_NEW_ADU", + "REVENT_NO_NEW_ADU", + "REVENT_DU_RECV", + "REVENT_ALL_DU_RECV", + "REVENT_CLOSE_CALLED", + "REVENT_CLOSE_RECV", + "REVENT_CLOSE_RETURN", + "REVENT_RESET" +}; + + +mcl_fsm::mcl_fsm () +{ + this->tx_state = TSTATE_NIL; + this->rx_state = RSTATE_NIL; +} + + +mcl_fsm::~mcl_fsm () +{ + this->tx_state = TSTATE_NIL; + this->rx_state = RSTATE_NIL; +} + + +void +mcl_fsm::update_tx_state (mcl_cb *const mclcb, mcl_tx_events event) +{ + mcl_tx_states new_state; + + TRACELVL(5, (mcl_stdout, "-> mcl_fsm::update_tx_state: event=%s\n", + this->print_tx_event(mclcb, event))) + ASSERT (event >= TEVENT_OPEN_CALLED && event <= TEVENT_RESET); + new_state = next_tx_state[this->tx_state][event]; + if (new_state == TSTATE_INVALID) { + PRINT_ERR((mcl_stderr, + "mcl_fsm::update_tx_state: ERROR, event %s invalid in state %s\n", + this->print_tx_event(mclcb, event), + this->print_tx_state(mclcb))) + mcl_exit(1); + } + this->tx_state = new_state; + TRACELVL(5, (mcl_stdout, "<- mcl_fsm::update_tx_state: new_state %s\n", + this->print_tx_state(mclcb))) +} + + +void +mcl_fsm::update_rx_state (class mcl_cb *const mclcb, mcl_rx_events event) +{ + mcl_rx_states new_state; + + TRACELVL(5, (mcl_stdout, "-> mcl_fsm::update_rx_state: event=%s\n", + this->print_rx_event(mclcb, event))) + ASSERT (event >= REVENT_OPEN_CALLED && event <= REVENT_CLOSE_RETURN); + new_state = next_rx_state[this->rx_state][event]; + if (new_state == RSTATE_INVALID) { + PRINT_ERR((mcl_stderr, + "mcl_fsm::update_rx_state: ERROR, event %s invalid in state %s\n", + this->print_rx_event(mclcb, event), + this->print_rx_state(mclcb))) + mcl_exit(1); + } + this->rx_state = new_state; + TRACELVL(5, (mcl_stdout, "<- mcl_fsm::update_rx_state: new_state %s\n", + this->print_rx_state(mclcb))) +} + + +const char * +mcl_fsm::print_tx_state (class mcl_cb *const mclcb) const +{ + ASSERT(this->tx_state >= TSTATE_NIL && this->tx_state <= TSTATE_INVALID); + return tx_states_msg[this->tx_state]; + +} + + +const char * +mcl_fsm::print_rx_state (class mcl_cb *const mclcb) const +{ + ASSERT(this->rx_state >= RSTATE_NIL && this->rx_state <= RSTATE_INVALID); + return rx_states_msg[this->rx_state]; +} + + +const char * +mcl_fsm::print_tx_event (class mcl_cb *const mclcb, mcl_tx_events event) const +{ + ASSERT(event >= TEVENT_NIL && event <= TEVENT_RESET); + return tx_events_msg[event]; + +} + + +const char * +mcl_fsm::print_rx_event (class mcl_cb *const mclcb, mcl_rx_events event) const +{ + ASSERT(event >= REVENT_NIL && event <= REVENT_CLOSE_RETURN); + return rx_events_msg[event]; +} + + +bool +mcl_fsm::is_opened (mcl_cb *const mclcb) const +{ + mcl_tx_rx_mode mode = mclcb->get_mode(); + if (mode == MCL_IS_A_SENDER_ONLY) { + return (this->tx_state >= TSTATE_READY); + } else if (mode == MCL_IS_A_RECEIVER_ONLY) { + return (this->rx_state >= RSTATE_READY); + } + mcl_exit(-1); // impossible, unsupported mode + return false; // to avoid warning +} + + +bool +mcl_fsm::can_send_data (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_sender()); + return (this->tx_state == TSTATE_IN_TX || + this->tx_state == TSTATE_FINISH_TX); +} + + +bool +mcl_fsm::can_recv_data (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_receiver()); + return (this->rx_state == RSTATE_READY || /* req to wait for 1st NEW_ADU */ + this->rx_state == RSTATE_IN_RX || + this->rx_state == RSTATE_FINISH_RX); +} + + +bool +mcl_fsm::finish_tx (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_sender()); + return(this->tx_state == TSTATE_FINISH_TX); +} + + +bool +mcl_fsm::no_new_adu (mcl_cb *const mclcb) const +{ + mcl_tx_rx_mode mode = mclcb->get_mode(); + if (mode == MCL_IS_A_SENDER_ONLY) { + return (this->tx_state == TSTATE_FINISH_TX || + this->tx_state == TSTATE_END || + this->tx_state == TSTATE_CLOSED); + } else if (mode == MCL_IS_A_RECEIVER_ONLY) { + return (this->rx_state == RSTATE_FINISH_RX || + this->rx_state == RSTATE_END || + this->rx_state == RSTATE_CLOSE_RX || + this->rx_state == RSTATE_CLOSED); + } + mcl_exit(-1); // impossible, unsupported mode + return false; // to avoid warning +} + + +bool +mcl_fsm::no_new_undup_du (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_receiver()); + return (this->rx_state == RSTATE_END || + this->rx_state == RSTATE_CLOSE_RX || + this->rx_state == RSTATE_CLOSED); +} + + +bool +mcl_fsm::close_already_rx (mcl_cb *const mclcb) const +{ + ASSERT(mclcb->is_a_receiver()); + return (this->rx_state == RSTATE_CLOSE_RX || + this->rx_state == RSTATE_CLOSED); +} + + +bool +mcl_fsm::close_can_return (mcl_cb *const mclcb) const +{ + mcl_tx_rx_mode mode = mclcb->get_mode(); + if (mode == MCL_IS_A_SENDER_ONLY) { + return (this->tx_state == TSTATE_CLOSED); + } else if (mode == MCL_IS_A_RECEIVER_ONLY) { + return (this->rx_state == RSTATE_CLOSED); + } + mcl_exit(-1); // impossible, unsupported mode + return false; // to avoid warning +} + + +bool +mcl_fsm::is_closed (mcl_cb *const mclcb) const +{ + mcl_tx_rx_mode mode = mclcb->get_mode(); + if (mode == MCL_IS_A_SENDER_ONLY) { + return (this->tx_state == TSTATE_CLOSED || + this->tx_state == TSTATE_NIL); + } else if (mode == MCL_IS_A_RECEIVER_ONLY) { + return (this->rx_state == RSTATE_CLOSED || + this->rx_state == RSTATE_NIL); + } + mcl_exit(-1); // impossible, unsupported mode + return false; // to avoid warning +} + diff --git a/src/norm/mcl_fsm.h b/src/norm/mcl_fsm.h new file mode 100644 index 0000000..c8807b7 --- /dev/null +++ b/src/norm/mcl_fsm.h @@ -0,0 +1,231 @@ +/* $Id: mcl_fsm.h,v 1.3 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_FSM_H +#define MCL_FSM_H + +#include "mcl_cb.h" + +/** + * SENDER's FSM (Finite State Machine). + */ +enum mcl_tx_states { + TSTATE_NIL = 0, + TSTATE_READY, + TSTATE_IN_TX, + TSTATE_FINISH_TX, + TSTATE_END, + TSTATE_CLOSED, + TSTATE_INVALID +}; + +enum mcl_tx_events { + TEVENT_NIL = 0, + TEVENT_OPEN_CALLED, /* application has called mcl_open */ + TEVENT_NEW_ADU, /* tx: mcl_send called, rx: NEW ADU received */ + TEVENT_ALL_DU_SENT, /* all the DUs have been sent */ + TEVENT_CLOSE_CALLED, /* application has called mcl_close */ + TEVENT_CLOSE_SENT, /* CLOSE sent to peer */ + TEVENT_CLOSE_RETURN, /* mcl_close just returned */ + TEVENT_ABORT, /* mcl_abort called */ + TEVENT_RESET /* mcl_abort called */ +}; + + +/** + * RECEIVER's FSM (Finite State Machine). + */ +enum mcl_rx_states { + RSTATE_NIL = 0, + RSTATE_READY, + RSTATE_IN_RX, + RSTATE_FINISH_RX, + RSTATE_END, + RSTATE_CLOSE_RX, /* CLOSE has been received */ + RSTATE_CLOSED, + RSTATE_INVALID +}; + +enum mcl_rx_events { + REVENT_NIL = 0, + REVENT_OPEN_CALLED, /* application has called mcl_open */ + REVENT_NEW_ADU, /* NEW_ADU received */ + REVENT_NO_NEW_ADU, /* NO_NEW_ADU received */ + REVENT_DU_RECV, /* DU received */ + REVENT_ALL_DU_RECV, /* all the DUs have been received */ + REVENT_CLOSE_CALLED, /* application has called mcl_close */ + REVENT_CLOSE_RECV, /* CLOSE sent to peer */ + REVENT_CLOSE_RETURN /* mcl_close just returned */ +}; + + +/** + * Class defining the Finite state machine of either a sender or a receiver. + */ +class mcl_fsm { + +public: + /****** Public Members ************************************************/ + mcl_fsm (); + ~mcl_fsm (); + /** + * Update the current tx (resp. rx) state with a new event. + * @param mclcb + * @param event new tx (resp. rx) event + * @return returns nothing but calls exit in case of invalid + * transition + */ + void update_tx_state (class mcl_cb *const mclcb, mcl_tx_events event); + void update_rx_state (class mcl_cb *const mclcb, mcl_rx_events event); + /** + * Get current state. + * @param mclcb + * @return State + */ + mcl_tx_states get_tx_state (class mcl_cb *const mclcb) const; + mcl_rx_states get_rx_state (class mcl_cb *const mclcb) const; + + /** + * Create a string for the current state. + * The buffer containing the string is statically allocated in + * the mcl_fsm class. Do not free it! + * @param mclcb + * @return String + */ + const char *print_tx_state (class mcl_cb *const mclcb) const; + const char *print_rx_state (class mcl_cb *const mclcb) const; + + /** + * Create a string for the event. + * The buffer containing the string is statically allocated in + * the mcl_fsm class. Do not free it! + * @param mclcb + * @param event tx (resp. rx) event to print + * @return String + */ + const char *print_tx_event (class mcl_cb *const mclcb, mcl_tx_events event) const; + const char *print_rx_event (class mcl_cb *const mclcb, mcl_rx_events event) const; + + /** + * Is the session (SENDER or RECEIVER) created, i.e. mcl_open() called? + * @return boolean + */ + bool is_opened (mcl_cb *const mclcb) const; + + /** + * Can we send data on this session? + * @param mclcb + * @return boolean + */ + bool can_send_data (mcl_cb *const mclcb) const; + + /** + * Is the receiver in a state where data can be received? + * Receiver specific function. + * @param mclcb + * @return boolean + */ + bool can_recv_data (mcl_cb *const mclcb) const; + + /** + * Are we in FINISH_TX state? + * Sender specific function. + * @param mclcb + * @return boolean + */ + bool finish_tx (mcl_cb *const mclcb) const; + + /** + * Do we expect new ADUs or not? + * Sender and receiver function. + * @param mclcb + * @return boolean + */ + bool no_new_adu (mcl_cb *const mclcb) const; + + /** + * Do we expect new DUs or do we have everything we need? + * Receiver specific function. + * @param mclcb + * @return boolean + */ + bool no_new_undup_du (mcl_cb *const mclcb) const; + + /** + * Did we already receive a CLOSE sig from the source or did we + * already receive all the expected DUs and appli issued a close()? + * If yes, then we can ignore a new CLOSE sig. + * Receiver specific function. + * @param mclcb + * @return boolean + */ + bool close_already_rx (mcl_cb *const mclcb) const; + + /** + * Should a call to mcl_close() return control to the application? + * Sender and receiver function. + * @param mclcb + * @return boolean + */ + bool close_can_return (mcl_cb *const mclcb) const; + + /** + * Is the session (SENDER or RECEIVER) closed? + * @param mclcb + * @return boolean + */ + bool is_closed (mcl_cb *const mclcb) const; + + /****** Public Attributes *********************************************/ + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + mcl_tx_states tx_state; + mcl_rx_states rx_state; + + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +/** + * Get current state. + * @return State + */ +inline mcl_tx_states +mcl_fsm::get_tx_state (class mcl_cb *const mclcb) const +{ + return this->tx_state; +} + + +inline mcl_rx_states +mcl_fsm::get_rx_state (class mcl_cb *const mclcb) const +{ + return this->rx_state; +} + +#endif // MCL_FSM_H + diff --git a/src/norm/mcl_group_mgmt.cpp b/src/norm/mcl_group_mgmt.cpp new file mode 100644 index 0000000..2a0e3bc --- /dev/null +++ b/src/norm/mcl_group_mgmt.cpp @@ -0,0 +1,96 @@ +/* $Id: mcl_group_mgmt.cpp,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * group management class + */ + +#include "mcl_includes.h" + + +mcl_group_mgmt::mcl_group_mgmt () +{ + head = tail = NULL; + cur_member = NULL; + memset(member_tab, 0, sizeof(member_tab)); + nb_of_members = 0; +} + + +mcl_group_mgmt::~mcl_group_mgmt () +{ + mcl_node *m; + + set_member_iter_to_head(); + while ((m = get_next_member()) != NULL) { + remove_member(m); + delete m; + } + head = tail = NULL; + cur_member = NULL; + memset(member_tab, 0, sizeof(member_tab)); + nb_of_members = 0; +} + + +// add a member to list of members known by MCL-NORM +mcl_error_status +mcl_group_mgmt::add_member (mcl_node *const mem) +{ + return MCL_OK; +} + + +// remove a member to list of members known by MCL-NORM +mcl_error_status +mcl_group_mgmt::remove_member (mcl_node *const mem) +{ + mcl_node *m; + + if (!(m = find_member_by_id(mem->get_id()))) { + // error, not found! + return MCL_ERROR; + } + return MCL_OK; + +} + + +mcl_node * +mcl_group_mgmt::find_member_by_id (int id) +{ + return NULL; +} + + +INT32 +mcl_group_mgmt::get_member_stats (mcl_node *const mem) +{ + return 0; +} + + +mcl_node * +mcl_group_mgmt::get_worst_member (void) +{ + return NULL; +} + diff --git a/src/norm/mcl_group_mgmt.h b/src/norm/mcl_group_mgmt.h new file mode 100644 index 0000000..7979f6f --- /dev/null +++ b/src/norm/mcl_group_mgmt.h @@ -0,0 +1,175 @@ +/* $Id: mcl_group_mgmt.h,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_GROUP_MGMT_H +#define MCL_GROUP_MGMT_H + +#include "mcl_node.h" + + +/** + * Group management class. + * Only considers the group members, i.e. the receivers of a multicast group. + */ +class mcl_group_mgmt { +public: + mcl_group_mgmt (); + ~mcl_group_mgmt (); + + /****** Member (i.e. receiver) list management ************************/ + + /** + * Add a member to list of members known by MCL-NORM. + * @param mem new member to add + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status add_member (mcl_node *const mem); + + /** + * Remove a member to list of members known by MCL-NORM. + * @param mem member to remove + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status remove_member (mcl_node *const mem); + + /* + * Iteration functions on the member list + */ + + /** Return the current number of members in the list. */ + INT32 get_nb_of_members (void); + + /** + * Find the member with this id. + * This function also resets the current member pointer to this one. + * @returns a member if found, or NULL if error + */ + mcl_node *find_member_by_id (int id); + + /** + * Reset the member list iteration to head. + * Next call to get_next_member will return the first node in list + * (if any), and following calls the node after. + */ + void set_member_iter_to_head (void); + + /** + * Reset the member list iteration to tail. + * Next call to get_prev_member will return the last node in list + * (if any), and following calls the node before. + */ + void set_member_iter_to_tail (void); + + /** + * Iteration, from current position. + * Be carefull not to mix get_next_member() and get_prev_member() + * in the same iteration (will not work!). + * returns a member, or NULL if nothing or at the end of list + */ + mcl_node *get_next_member (void); + + /** + * Iteration, from current position. + * Be carefull not to mix get_next_member() and get_prev_member() + * in the same iteration (will not work!). + * returns a member, or NULL if nothing or at the end of list + */ + mcl_node *get_prev_member (void); + + /****** Statistics ****************************************************/ + + /** + * Get the statistics for a given member. + */ + INT32 get_member_stats (mcl_node *const mem); + + /** + * Get the member having the worst statisitics (only one). + * @returns a member, or NULL if no member in list + */ + mcl_node *get_worst_member (void); + +private: + /* + * iterations + */ + mcl_node *head, *tail; // doubly linked list of members, no + // cycle: tail->next==head->prev==NULL + mcl_node *cur_member; // current position in iteration. + // this is the member that will returned + // by get_next/prev_member() + static const INT32 MAX_NB_OF_MEMBERS = 1024; + mcl_node *member_tab[MAX_NB_OF_MEMBERS]; + // table for direct id to member access + INT32 nb_of_members; // number of members in the list +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline INT32 +mcl_group_mgmt::get_nb_of_members (void) +{ + return this->nb_of_members; +} + +inline void +mcl_group_mgmt::set_member_iter_to_head (void) +{ + this->cur_member = this->head; +} + +inline void +mcl_group_mgmt::set_member_iter_to_tail (void) +{ + this->cur_member = this->tail; +} + +inline mcl_node * +mcl_group_mgmt::get_next_member (void) +{ + mcl_node *n = this->cur_member; + + if (n) { + this->cur_member = this->cur_member->get_next(); + return n; + } else { + return NULL; + } +} + +inline mcl_node * +mcl_group_mgmt::get_prev_member (void) +{ + mcl_node *n = this->cur_member; + + if (n) { + this->cur_member = this->cur_member->get_prev(); + return n; + } else { + return NULL; + } +} + + +#endif // MCL_GROUP_MGMT_H diff --git a/src/norm/mcl_includes.h b/src/norm/mcl_includes.h new file mode 100644 index 0000000..6a3b386 --- /dev/null +++ b/src/norm/mcl_includes.h @@ -0,0 +1,135 @@ +/* $Id: mcl_includes.h,v 1.7 2004/12/10 10:37:14 chneuman Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * System and MCL includes. + * Included by all source files. + */ + + +/****** System includes *******************************************************/ + +#ifdef SOLARIS +#define __EXTENSIONS__ // XXX: we have pbs without on Solaris 2.5.1 +#endif + +#include +#include +//#include +#include +using namespace std; + +#include +extern int errno; +#include +#include +#include +#include +#include +#include + +#if defined(DEBUG) && defined(MPATROL) && !defined(WIN32) +#include +#else +#include +#endif +#include // required by _set_new_handler on linux + +#ifdef WIN32 /* WIN32 */ + +#include +#include +#include +#include +#include + +#else /* UNIX Systems */ + +#include +#include /* for MAXINT */ +#include +#include +#include +#include +#include +#include +#if defined(SOLARIS) || defined(FREEBSD) +#include +#endif /* SOLARIS || FREEBSD */ +#include +#include +#include +#include +#include +#include + +#endif /* OS */ + + +/****** MCL includes **********************************************************/ + +#include "../common/mcl_types.h" // First: define portable types +#include "../common/mcl_osdep.h" +#include "mcl_profile.h" // Second: MCL-NORM default profile +#include "../common/mcl_defines.h" // Third: major defines/constants +#include "../common/mcl_lib_api.h" + +#include "../common/mcl_version.h" +#include "../common/mcl_addr.h" +#include "../common/mcl_debug.h" +#include "../common/mcl_itime.h" +#include "../common/mcl_list.h" +#ifdef RSE_FEC +#include "../common/rse_fec.h" +#endif + +#include "mcl.h" +#include "mcl_norm_hdr.h" +#include "mcl_adu.h" +#include "mcl_du.h" +#include "mcl_block.h" +#include "mcl_cb.h" // needed by all the following class decl. +#include "mcl_node.h" +#include "mcl_fsm.h" +#include "mcl_timer_handler.h" +#include "mcl_timer.h" +#include "../common/mcl_periodic_timer.h" +#include "mcl_periodic_proc.h" +#include "mcl_fec.h" +#include "mcl_stats.h" +#include "mcl_ses_channel.h" +#include "mcl_norm_pkt_mgmt.h" +#include "mcl_tx.h" +#include "mcl_tx_window.h" +#include "mcl_tx_ctrl.h" +//#include "mcl_tx_pgmcc.h" not yet... +//#include "mcl_tx_tfmcc.h" not yet... +#include "mcl_tx_storage.h" +#include "mcl_rx.h" +#include "mcl_rx_window.h" +#include "mcl_rx_thread.h" +#include "mcl_rx_ctrl.h" +//#include "mcl_rx_pgmcc.h" not yet... +//#include "mcl_rx_tfmcc.h" not yet... +#include "mcl_rx_storage.h" +#include "mcl_fsm.h" + + diff --git a/src/norm/mcl_lib.cpp b/src/norm/mcl_lib.cpp new file mode 100644 index 0000000..dffcece --- /dev/null +++ b/src/norm/mcl_lib.cpp @@ -0,0 +1,928 @@ +/* $Id: mcl_lib.cpp,v 1.10 2004/09/22 14:10:22 chneuman Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * This file contains the entry functions of the MCL library. + */ + +#include "mcl_includes.h" + +int mcl_ctl2 (mcl_cb *mclcb, int optname, void *optvalue, int optlen); + +/****** external functions of the library *************************************/ + +/** + * Open an MCL-NORM session. + * @param mode defines the kind of session ("r", "w") + * @return returns to appli a unique identifier if ok, or < 0 in case of error + */ +int +mcl_open (const char* mode) +{ + mcl_cb *mclcb; + mcl_tx_rx_mode mcl_mode; + + // check mode and translate to internal mcl mode + if (!strcmp("w", mode)) { + mcl_mode = MCL_IS_A_SENDER_ONLY; + } else if (!strcmp("r", mode)) { + mcl_mode = MCL_IS_A_RECEIVER_ONLY; + } else { + PRINT_ERR((mcl_stderr, "mcl_open: ERROR unknown mode %s\n", mode)) + goto bad; + } + mclcb = new mcl_cb(mcl_mode); // to do immediately before anything else + if (!mclcb) { + PRINT_ERR((mcl_stderr, "mcl_open: ERROR, mclcb constructor failed\n")) + goto bad; + } + TRACELVL(5, (mcl_stdout, "<- mcl_open: \"%s\" return %d\n", + mode, (int)mclcb->get_id())) + return (int)(mclcb->get_id()); + +bad: + PRINT_ERR((mcl_stderr, "mcl_open: ERROR\n")) + return -1; +} + + +/** + * Close the MCL session. + * @param id MCL session identifier + * @return returns 0 if ok, or < 0 in case of error + */ +int +mcl_close (int id) +{ + mcl_cb *mclcb; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_close: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + TRACELVL(5, (mcl_stdout, "-> mcl_close: id=%d\n", id)) + + if (mclcb->is_a_sender() && mclcb->fsm.can_send_data(mclcb)) { + /* + * this is a sender + * data has already been submitted, so remember there + * will be no more ADUs but wait before sending a + * NORM_CMD_NO_NEW_OBJECTS packet (will be done at + * end of data tx and all pending control operations + * performed) + */ + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_CALLED); + mclcb->tx.set_no_new_adu(mclcb); + // wait till everything has been sent... + while (!mclcb->fsm.close_can_return(mclcb)) { + TRACELVL(5, (mcl_stdout, " mcl_close: (sender) wait a bit...\n")) + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + TRACELVL(5, (mcl_stdout, " mcl_close: (sender) end of sleep...\n")) + } + //mclcb->tx_ctrl.send_close_pkt(mclcb); + //mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_SENT); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_RETURN); + } else if (mclcb->is_a_sender()) { + /* + * this is a sender + * data has never been submitted => send a CLOSE and return + */ + mclcb->finish_session_init_if_needed(); // yes, really needed! + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_CALLED); + mclcb->tx.set_no_new_adu(mclcb); + mclcb->tx_ctrl.send_close_pkt(mclcb); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_SENT); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_RETURN); + } else { + /* + * this is a receiver + */ + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_CALLED); + while (!mclcb->fsm.close_can_return(mclcb)) { + TRACELVL(5, (mcl_stdout, " mcl_close: (receiver) wait a bit...\n")) + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + }; + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_RETURN); + } + /* + * de-register the session (e.g. used by the periodic_timer_thread) + */ + mclcb_tab[id] = NULL; + /* + * destroy the rx thread now... + */ +//#ifndef WIN32 +// if (mclcb->rx_thread.get_rx_thread_id() != 0) { +// pthread_cancel(mclcb->rx_thread.get_rx_thread_id()); +// } +//#endif + mclcb->unlock(); /* tx and rx threads might be blocked */ +#ifndef WIN32 + if (mclcb->rx_thread.get_rx_thread_id() != 0) { + pthread_join(mclcb->rx_thread.get_rx_thread_id(), NULL); + } +#endif + mclcb->free_everything(); /* free everything... */ + TRACELVL(5, (mcl_stdout, "<- mcl_close:\n")) + delete mclcb; /* ...including mclcb itself */ + return (close(id)); +} + + +/* + * close the session immediately and send CLOSE messages if we + * are a source. + */ +int +mcl_abort (int id) +{ + mcl_cb *mclcb; + int err; /* return code from close */ + int trylock_err; /* return code from trylock: 0 if ok, or EBUSY*/ + static bool in_abort = false;/* return if true (someone else in abort)*/ + + if (in_abort) { + //TRACE((mcl_stdout, "<- mcl_abort: someone else in abort\n")) + return 0; /* don't try to call close in abort mode */ + } + in_abort = true; /* take "lock" */ + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_abort: ERROR, bad id %d\n", id)) + in_abort = false; /* release "lock" */ + return 0; /* don't try to call close in abort mode */ + } + /* + * do not call lock in an async signal environment... + * this is a problem as mcl_abort is usually called after a CTRL-C + * so, use trylock instead and take lock only if available. + */ + trylock_err = mclcb->trylock(); + TRACELVL(5, (mcl_stdout, "-> mcl_abort: id=%d\n", id)) + if (mclcb->is_a_sender()) { + /* send a CLOSE and return, no matter which is current state */ + mclcb->finish_session_init_if_needed(); /* yes really needed! */ + mclcb->fsm.update_tx_state(mclcb, TEVENT_ABORT); + mclcb->tx_ctrl.send_close_pkt(mclcb); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_SENT); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_RETURN); + } else { + if (mclcb->fsm.is_opened(mclcb)) { + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_CALLED); + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_RETURN); + } + /* else already in RSTATE_NIL, do nothing */ + } + /* + * de-register the session (e.g. used by the periodic_timer_thread) + */ + mclcb_tab[id] = NULL; + /* + * destroy the rx thread now... + */ +//#ifndef WIN32 +// if (mclcb->rx_thread.get_rx_thread_id() != 0) { +// pthread_cancel(mclcb->rx_thread.get_rx_thread_id()); +// } +//#endif + if (trylock_err == 0) { + mclcb->unlock(); /* tx and rx threads might be blocked */ + } +#ifndef WIN32 + if (mclcb->rx_thread.get_rx_thread_id() != 0) { + // XXX: sometimes blocks... TODO fix it! + // pthread_join(mclcb->rx_thread.get_rx_thread_id(), NULL); + } +#endif + mclcb->free_everything(); /* free everything... */ + TRACELVL(5, (mcl_stdout, "<- mcl_abort:\n")) + delete mclcb; /* ...including mclcb itself */ + err = close(id); + in_abort = false; /* release "lock" */ + return err; +} + + +/** + * Get or set control parameters for the session. + * Follows the Unix ioctl() syscall interface. + * Warning: usually the tx and rx contexts are still not fully initialized! + * This is only done during the first call to mcl_send or mcl_recv... + * + * @param id MCL session identifier + * @param optname the option to set/get/change + * @param optvalue the associated value set or read + * @return returns 0 if ok, or < 0 in case of error + */ +int +mcl_ctl (int id, + int optname, + void *optvalue, + int optlen) +{ + mcl_cb *mclcb; + int err; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_ctl: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + if (!mclcb->fsm.is_opened(mclcb)) { + PRINT_ERR((mcl_stderr, "mcl_ctl: ERROR not opened\n")) + mclcb->unlock(); + return -1; + } + TRACELVL(5, (mcl_stdout, "-> mcl_ctl: id=%d\n", id)) + // call the internal ctl function where work will be done + err = mcl_ctl2(mclcb, optname, optvalue, optlen); + TRACELVL(5, (mcl_stdout, "<- mcl_ctl: return %d\n", err)) + mclcb->unlock(); + return err; +} + + +/** + * private internal version of the MCL control function + */ +int +mcl_ctl2 (mcl_cb *mclcb, + int optname, + void *optvalue, + int optlen) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_ctl2: optname=%d, optvalue=x%x, optlen=%d\n", + optname, (int)optvalue, optlen)) + /* + * called first (before mcl_open) to set the mcl options + * or call the internal application + */ + switch (optname) { + + case MCL_OPT_VERBOSITY: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_VERBOSITY ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + if (mclcb->set_verbosity(*(INT32*)optvalue) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_VERBOSITY ERROR: verbose arg %d out of range\n", *(int*)optvalue)) + mclcb->set_verbosity(0); // set a conservative value + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_VERBOSITY (%d)\n", mclcb->get_verbosity())) + break; + + case MCL_OPT_STATS: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_STATS ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if (mclcb->set_stats_level(*(INT32*)optvalue) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_STATS ERROR: statistics arg %d out of range\n", *(int*)optvalue)) + mclcb->set_stats_level(0); // set a conservative value + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_STATS (%d)\n", mclcb->get_stats_level())) + break; + +#if 0 + case MCL_OPT_NETIF: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, "mcl_ctl: MCL_OPT_NETIF ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + mclcb->ses_channel.mcast_if.set_addr(*(UINT32*)optvalue); + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_NETIF (%d)\n", mclcb->ses_channel.mcast_if.get_addr())) + break; +#endif + case MCL_OPT_SET_NETIF_NAME: + if (!optvalue || optlen <= 0 || optlen > MAX_NAME_LEN) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NETIF_NAME ERROR: null optvalue or out of range optlen (got %d, expected ]0; %d])\n", + optlen, MAX_NAME_LEN)) + goto error; + } + if ((mclcb->ses_channel.mcast_if_name = (char*)calloc(1, optlen + 1)) == NULL) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NETIF_NAME ERROR: calloc failed.\n")) + goto error; + } + strncpy(mclcb->ses_channel.mcast_if_name, (char*)optvalue, optlen); + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_SET_NETIF_NAME (%s)\n", mclcb->ses_channel.mcast_if_name)) + break; + + case MCL_OPT_SET_NETIF_ADDR: + /* specify sockaddr of the network interface to use */ + if (!optvalue) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NETIF_ADDR ERROR: null optvalue\n")) + goto error; + } + switch (optlen) { + case (sizeof(struct sockaddr_in)): { + struct sockaddr_in sin; + + sin = *(struct sockaddr_in*)optvalue; + /* assumes addr/port in network order */ + mclcb->ses_channel.mcast_if_addr = new mcl_addr(); + mclcb->ses_channel.mcast_if_addr->set_addr_struct(&sin); + break; + } +#ifdef INET6 + case (sizeof(struct sockaddr_in6)): { + struct sockaddr_in6 sin6; + + sin6 = *(struct sockaddr_in6*)optvalue; + /* assumes addr/port in network order */ + mclcb->ses_channel.mcast_if_addr = new mcl_addr(); + mclcb->ses_channel.mcast_if_addr->set_addr_struct(&sin6); + break; + } +#endif // INET6 + default: + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_NETIF_ADDR ERROR: bad optlen (got %d, expected %d or %d)\n", + optlen, sizeof(struct sockaddr_in), + sizeof(struct sockaddr_in6))) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_NETIF_ADDR (%s)\n", + mclcb->ses_channel.mcast_if_addr->get_addr_string())) + break; + + case MCL_OPT_PORT: { + UINT16 p; // port + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_PORT ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + /* port in host byte order */ + p = *(int*)optvalue; + mclcb->ses_channel.ses_addr.set_port(p); + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_PORT (%d)\n", p)) + break; + } + + case MCL_OPT_ADDR: + if (!optvalue || optlen != sizeof(UINT32)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_ADDR ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(UINT32))) + goto error; + } + /* addr in host byte order */ + mclcb->ses_channel.ses_addr.set_addr(*(UINT32*)optvalue); + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_ADDR (%s addr %s)\n", + (mclcb->ses_channel.is_mcast_session() ? "multicast" : "unicast"), mclcb->ses_channel.ses_addr.get_addr_string())) + break; + +#if 0 + case MCL_OPT_SRC_ADDR: + if (!optvalue || optlen != sizeof(uint32_t)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SRC_ADDR ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(uint32_t))) + goto error; + } + /* addr in host byte order */ + mclcb->src_addr = *(uint32_t*)optvalue; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_SRC_ADDR\n")) + break; + + case MCL_OPT_BIND: { + struct sockaddr_in sin; + /* specify sockaddr to use like a bind syscall */ + if (!optvalue || optlen != sizeof(struct sockaddr_in)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_BIND ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(struct sockaddr_in))) + goto error; + } + /* addr/port in network order => change to host order */ + sin = *(struct sockaddr_in*)optvalue; + mclcb->addr = ntohl(sin.sin_addr.s_addr); + mclcb->myport = ntohs(sin.sin_port); + if (IN_MULTICAST(mclcb->addr)) + mclcb->is_multicast = 1; + else + mclcb->is_multicast = 0; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_BIND (%s addr)\n", + (mclcb->is_multicast ? "multicast" : "unicast"))) + break; + } +#endif // 0 + + case MCL_OPT_BIND: + /* specify sockaddr to use like a bind syscall */ + if (!optvalue) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_BIND ERROR: null optvalue\n")) + goto error; + } + switch (optlen) { + case (sizeof(struct sockaddr_in)): { + struct sockaddr_in sin; + + sin = *(struct sockaddr_in*)optvalue; + /* assumes addr/port in network order */ + mclcb->ses_channel.ses_addr.set_addr_struct(&sin); + break; + } +#ifdef INET6 + case (sizeof(struct sockaddr_in6)): { + struct sockaddr_in6 sin6; + + sin6 = *(struct sockaddr_in6*)optvalue; + /* assumes addr/port in network order */ + mclcb->ses_channel.ses_addr.set_addr_struct(&sin6); + break; + } +#endif // INET6 + default: + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_BIND ERROR: bad optlen (got %d, expected %d or %d)\n", + optlen, sizeof(struct sockaddr_in), + sizeof(struct sockaddr_in6))) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_BIND (%s IPv6 addr %s)\n", + (mclcb->ses_channel.ses_addr.is_multicast_addr() ? "multicast" + : "unicast"), + mclcb->ses_channel.ses_addr.get_addr_string())) + break; + + case MCL_OPT_TTL: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TTL ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + mclcb->ses_channel.ttl = *(UINT32*)optvalue; + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_TTL (%d)\n", + mclcb->ses_channel.ttl)) + if (mclcb->ses_channel.ttl > 127) { + /* ttl 0 means do not leave host which is valid */ + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TTL ERROR: TTL %d out of range ([0; %d]), reset to 1.\nNB: TTL == 0 means that packets won't leave the host\n", + mclcb->ses_channel.ttl, 127)) + mclcb->ses_channel.ttl = 1; + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: ttl=%d\n", mclcb->ses_channel.ttl)) + break; + + case MCL_OPT_FEC_RATIO: + if (!optvalue || optlen != sizeof(float)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_FEC_RATIO ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(float))) + goto error; + } + if (mclcb->fec.set_fec_ratio(mclcb, *(float*)optvalue) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_FEC_RATIO failed for fec_ratio %f\n", + *(float*)optvalue)) + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_FEC_RATIO (%f)\n", *(float*)optvalue)) + break; + + case MCL_OPT_TX_PROFILE: /* select a pre-defined tx profile */ + mcl_tx_profile prof; + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TX_PROFILE ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + prof = (mcl_tx_profile)(*(int*)optvalue); + if (mclcb->tx.set_tx_profile(mclcb, prof) < 0) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TX_PROFILE: mcl_set_tx_profile() failed for profile %d\n", (int)prof)) + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_TX_PROFILE (%d)\n", (int)prof)) + break; + + case MCL_OPT_DATAGRAM_SIZE: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_DATAGRAM_SIZE ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + if (mclcb->set_max_datagram_size(*(int*)optvalue) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_DATAGRAM_SIZE ERROR: size %d out of range\n", + *(int*)optvalue)) + goto error; + } + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_DATAGRAM_SIZE (%d)\n", mclcb->get_max_datagram_size())) + break; + + case MCL_OPT_TX_RATE: { + int rate; + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, "mcl_ctl: MCL_OPT_TX_RATE ERROR: null optvalue or bad optlen (got %d, expected %d)\n", optlen, sizeof(int))) + goto error; + } + rate = *(int*)optvalue; /* in packets/s on base layer */ + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_TX_RATE (%d)\n", rate)) +#define MCL_MAX_TX_RATE 4000 + if (rate <= 0 || rate > MCL_MAX_TX_RATE) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TX_RATE ERROR: rate %d out of range ([1; %d] pkts/s)\n", + rate, MCL_MAX_TX_RATE)) + goto error; + } + mclcb->tx.set_bps_tx_rate(mclcb, rate); + break; + } + + case MCL_OPT_SET_FEC_CODE: /* set the FEC codec to be used */ + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FEC_CODE ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(int))) + goto error; + } + if ((*(int*)optvalue) < MCL_FEC_SCHEME_NULL || + (*(int*)optvalue) >= MCL_FEC_SCHEME_NB) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FEC_CODE ERROR: value out or range (got %d, expected [%d; %d])\n", + (*(int*)optvalue), + MCL_FEC_SCHEME_NULL, MCL_FEC_SCHEME_NB - 1)) + goto error; + } + if (mclcb->fec.set_fec_code(mclcb, (*(int*)optvalue)) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_SET_FEC_CODE WARNING: fec.set_fec_code(%d) failed\n", + (*(int*)optvalue))) + goto error; + } + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_SET_FEC_CODE (%d)\n", + (*(int*)optvalue))) + break; + + case MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC: + if (!optvalue || optlen != sizeof(int)) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC ERROR: null optvalue or bad optlen (got %d, expected %d)\n", + optlen, sizeof(UINT32))) + goto error; + } + *(int*)optvalue = mclcb->fec.get_k() * mclcb->get_payload_size(); + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC (%d)\n", + (*(int*)optvalue))) + break; + + case MCL_OPT_MOREABOUT: + TRACELVL(5, (mcl_stdout, " mcl_ctl: MCL_OPT_MOREABOUT\n")) + mcl_moreabout(); + break; + + case MCL_OPT_TMP_DIR: /* name of directory to use for temp files */ + if (!optvalue || optlen <= 0 || optlen >= MAX_FILE_NAME_LEN) { + PRINT_ERR((mcl_stderr, + "mcl_ctl: MCL_OPT_TMP_DIR ERROR: null optvalue or bad optlen (got %d, expected in ]0; %d[)\n", + optlen, MAX_FILE_NAME_LEN)) + goto error; + } + strncpy(mcl_tmp_dir_name, (char*)optvalue, optlen); + mcl_tmp_dir_name[MAX_FILE_NAME_LEN-1] = '\0'; /* security */ + /* update the mcl_stdout/err outputs */ + mcl_stdout_stderr_init(); + TRACELVL(5, (mcl_stdout, + " mcl_ctl: MCL_OPT_TMP_DIR %s\n", mcl_tmp_dir_name)) + break; + + default: + bool opt_found = false; +#ifdef RLC + if (rlc_ctl(mclcb, optname, optvalue, optlen) == MCL_OK) { + opt_found = true; + } +#endif /* RLC */ + if (opt_found == false) { + PRINT_ERR((mcl_stderr, "mcl_ctl: ERROR: unknown optname %d\n", optname)) + PRINT_ERR((mcl_stderr, "Check that the MCL lib has been compiled with the appropriate flags...\n")) + goto error; + } + break; + + } + TRACELVL(5, (mcl_stdout, "<- mcl_ctl2: ok\n")) + return 0; + +error: + TRACELVL(5, (mcl_stdout, "<- mcl_ctl2: error\n")) + return -1; +} + + +/** + * mcl_send data sending function. + * @param id MCL session identifier + * @param data data block; in MCL_OPT_REUSE_APPLI_TX_BUFFER mode, the + * data pointer must be the result of a standard + * malloc/calloc/realloc function call. + * @param len data block length in bytes + * @return number of bytes sent or -1 if error + */ +int +mcl_send (int id, + const void *data, + int len) +{ + return mcl_sendto(id, data, len, NULL, 0); +} + + +/** + * mcl_sendto data sending function. + * @param id MCL session identifier + * @param data data block; in MCL_OPT_REUSE_APPLI_TX_BUFFER mode, the + * data pointer must be the result of a standard + * malloc/calloc/realloc function call. + * @param len data block length in bytes + * @param saddr destination address (network byte order) + * @param saddr_len address length (the sockaddr struct is generic!) + * @return number of bytes sent or -1 if error + */ +int +mcl_sendto (int id, + const void *data, + int len, + const struct sockaddr *saddr, + int saddr_len) +{ + mcl_cb *mclcb; + mcl_adu *adu; /* ADU descriptor of the data buffer */ + mcl_addr addr; + //INT32 padded_len; /* size with padding to 0 for FEC */ +#ifdef MCL_USE_PROACTIVE_FEC + int i; + mcl_block *blk; + INT32 fec_desired; +#endif + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_sendto: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + TRACELVL(5, (mcl_stdout, "-> mcl_sendto: len=%d, saddr_len=%d\n", + len, saddr_len)) + mclcb->finish_session_init_if_needed(); + if (data == NULL && len == 0) { + /* + * the appli issued this call just to finish the init... + * nothing else to do, return. + */ + TRACELVL(5, (mcl_stdout, "<- mcl_sendto: no data, return\n")) + goto end; + } + if (!data || len <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: bad data or len argument\n")) + goto error; + } + if ((saddr_len == 0 && saddr != NULL) || + (saddr == NULL && saddr_len > 0)) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: bad address or address len argument\n")) + goto error; + } + // TO DO: accept sockaddr_in6 for IPv6... + if (saddr && saddr_len != sizeof(struct sockaddr_in)) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: bad addr or addr_len argument\n")) + goto error; + } + mclcb->fsm.update_tx_state(mclcb, TEVENT_NEW_ADU); + /* + * is there any room available in the tx window? + */ + while (!mclcb->tx_window.can_register_new_adu(mclcb)) { + TRACELVL(5, (mcl_stdout, " mcl_sendto: wait a bit for some room...\n")) + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + } + /* + * and can we actually send data? + */ + if (!mclcb->fsm.can_send_data(mclcb)) { + TRACELVL(5, (mcl_stdout, "<- mcl_sendto: ERROR, cannot send\n")) + goto error; + } + /* + * initialize the dest addr. + */ + if (saddr != NULL) { + // use the provided address + addr.set_addr_struct((struct sockaddr_in*)saddr); + } else { + // ...else use the default session addr + addr = mclcb->ses_channel.ses_addr; + } + /* + * create the adu descriptor and initialize its attributes... + * do not store data buffer yet... + */ + adu = new mcl_adu (mclcb, len, &addr); + /* + * insert the adu in the tx list... + */ + mclcb->tx.insert_adu(mclcb, adu); + /* + * store the application data... + */ + //padded_len = adu->get_padded_len(); + if (mclcb->tx_storage.store_adu_data (mclcb, adu, (char*) data) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: data buffer storage failed\n")) + goto error; + } + /* + * segment the adu... + */ + adu->segment_for_tx(mclcb); + /* + * store the adu (and all its dus) in the tx_window... + */ + mclcb->tx_window.register_new_adu(mclcb, adu); +#ifdef MCL_USE_PROACTIVE_FEC + /* + * create additional FEC DUs for each block for proactive FEC tx... + * these FEC DUs will automatically be scheduled for transmission + * once created by the encoding thread. + */ + for (i = adu->get_block_nb(), blk = adu->get_block_head(); + i > 0; i--, blk++) { +#ifdef LINUX + fec_desired = (int)(ceilf(MCL_PROACTIVE_FEC_RATIO * (float)(blk->du_nb))); +#else // ceilf does not exist... + fec_desired = (int)(ceil((double)MCL_PROACTIVE_FEC_RATIO * (double)(blk->du_nb))); +#endif // OS + if (mclcb->fec.encode(mclcb, blk, fec_desired) <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_sendto: ERROR: FEC encoding failed\n")) + goto error; + } + } +#endif + /* + * update stats + */ + mclcb->stats.adus_announced++; + //mclcb->stats.buf_space += adu->get_padded_len(); + mclcb->stats.buf_space += adu->get_len(); // ignore padding + if (mclcb->stats.buf_space > mclcb->stats.max_buf_space) + mclcb->stats.max_buf_space = mclcb->stats.buf_space; + if (mclcb->get_stats_level() > 0) + mclcb->stats.print_tx_stats(mclcb); + + TRACELVL(5, (mcl_stdout, "<- mcl_sendto: %d bytes sent\n", len)) +end: + mclcb->unlock(); + return len; + +error: + TRACELVL(5, (mcl_stdout, "<- mcl_sendto: ERROR, return -1\n")) + mclcb->unlock(); + return -1; +} + + +/** + * mcl_recv data sending function. + * @param id MCL session identifier + * @param buf pointer to data buffer + * @param len data buffer length in bytes + * @return number of bytes received or -1 if error + */ +int +mcl_recv (int id, + void *buf, + int len) +{ + int saddr_len = 0; + return mcl_recvfrom(id, buf, len, (struct sockaddr*)NULL, (int*)&saddr_len); +} + + +/** + * mcl_recvfrom data sending function. + * @param id MCL session identifier + * @param data pointer to data buffer + * @param len data buffer length in bytes + * @param saddr source address from which data was received (network byte order) + * @param saddr_len pointer to address length (sockaddr struct is generic!) + * @return number of bytes received or -1 if error + */ +int +mcl_recvfrom (int id, + void *buf, + int len, + struct sockaddr *saddr, + int *saddr_len) +{ + INT32 rlen = 0; + struct sockaddr tmp_saddr; + INT32 tmp_saddr_len = sizeof(tmp_saddr); + mcl_cb *mclcb; + + if (id >= MAX_NB_MCLCB || (mclcb = mclcb_tab[id]) == NULL) { + PRINT_ERR((mcl_stderr, "mcl_recvfrom: ERROR, bad id %d\n", id)) + return -1; + } + mclcb->lock(); + TRACELVL(5, (mcl_stdout, "-> mcl_recvfrom: len=%d, saddr_len ptr=x%x\n", + len, (UINT32)saddr_len)) + mclcb->finish_session_init_if_needed(); + if (buf == NULL || len == 0) { + /* + * the appli issued this call just to finish the init... + * nothing else to do, return. + */ + TRACELVL(5, (mcl_stdout, + "<- mcl_recvfrom: NULL reception buffer, return\n")) + rlen = 0; + goto end; + } + /* + * check if an adu is available and copy it to + * the application buffer + * XXX : use polling for the present... change it! + */ + while ((rlen = mclcb->rx.return_adu_to_appli(mclcb, (char*)buf, + (INT32)len, &tmp_saddr, + &tmp_saddr_len)) < 0) { + if (mclcb->fsm.no_new_undup_du(mclcb)) { + TRACELVL(5, (mcl_stdout, + "<- mcl_recvfrom: closed, return -1\n")) + goto error; + } + /* + * nothing received yet so wait a little bit (polling). + * the waiting time is a compromize... what should we use? + */ + mclcb->unlock(); + mcl_usleep(DFLT_POLLING_PERIOD); + mclcb->lock(); + }; + + /* + * copy back remote addr if appli is interested + */ + if (saddr) { + ASSERT(saddr_len > 0); + /*memcpy(saddr, &tmp_saddr, tmp_saddr_len);*/ + *saddr = tmp_saddr; + *saddr_len = tmp_saddr_len; + } + TRACELVL(5, (mcl_stdout, "<- mcl_recvfrom: %d bytes recvd from %s\n", + rlen, inet_ntoa(((struct sockaddr_in*)&tmp_saddr)->sin_addr))) +end: + mclcb->unlock(); + return rlen; + +error: + mclcb->unlock(); + return -1; +} + + diff --git a/src/norm/mcl_lib_api_norm.h b/src/norm/mcl_lib_api_norm.h new file mode 100644 index 0000000..5c36dd8 --- /dev/null +++ b/src/norm/mcl_lib_api_norm.h @@ -0,0 +1,136 @@ +/* $Id: mcl_lib_api_norm.h,v 1.5 2004/08/03 06:35:56 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_LIB_API_NORM_H +#define MCL_LIB_API_NORM_H + +/* + * MCL API definition, part II: the reliable multicast specific part of + * the MCL API. + * + * WARNING: This file must not be included by an application, only file: + * src/common/mcl_lib_api.h + * must be included! + */ + +enum mcl_tx_profile { + MCL_TX_PROFILE_LOW_RATE_INTERNET = 0, /* modem connection */ + MCL_TX_PROFILE_MID_RATE_INTERNET, /* eg with VPNs, xDSL */ + MCL_TX_PROFILE_HIGH_SPEED_INTERNET, /* several Mbps connection */ + MCL_TX_PROFILE_HIGH_SPEED_LAN /* 100Mbps ethernet LAN */ +}; + + +/** + * FEC schemes available. + * Use one of them for mcl_ctl(SET_FEC_CODE). + * A FEC scheme defines both the FEC codec and the way it is used, + * i.e. the {FEC Encoding ID; FEC Instance ID} tuple. + */ +enum mcl_fec_scheme { + MCL_FEC_SCHEME_NULL = 0, /* NULL code (i.e. no FEC encoding) */ + MCL_FEC_SCHEME_RSE_129_0 + /* Reed-Solomon erasure FEC code */ + //MCL_FEC_SCHEME_LDGM_STAIRCASE_132_0, + /* Low Density Generator Matrix-STAIRCASE */ + //MCL_FEC_SCHEME_LDGM_TRIANGLE_132_1 + /* Low Density Generator Matrix-TRIANGLE */ +}; +#define MCL_FEC_SCHEME_NB 2 /* Number of FEC schemes available */ + + +/* + * library options set with the mcl_ctl() function + */ +enum mcl_opt { + /* + * common options used by both sender and receiver + */ + MCL_OPT_PORT, /* port number (uni or multicast), HOST order*/ + /* argument: int (and not ushort!) */ + MCL_OPT_ADDR, /* address (uni or multicast), HOST order */ + /* argument: int */ + MCL_OPT_SRC_ADDR, /* (unicast) source address, HOST order, only */ + /* needed at a receiver. */ + /* argument: int */ + MCL_OPT_BIND, /* specify sockaddr struct, NETWORK byte order*/ + /* argument: struct sockaddr_in */ + MCL_OPT_TTL, /* specify TTL (time to live) in [0;127] range*/ + /* argument: int */ + MCL_OPT_STATS, /* collect various stats */ + /* argument: int */ + MCL_OPT_VERBOSITY, /* verbosity level */ + /* argument: int */ + MCL_OPT_DEBUG, /* no tx/rx thread to simplify debug */ + /* argument: none */ + MCL_OPT_MOREABOUT, /* version # and credits */ + /* argument: none */ + MCL_OPT_TMP_DIR, /* put temporary files in this directory */ + /* argument: a `\0' terminated string, size */ /* given */ + /* two multicast specific socket options - rarely required... */ + // MCL_OPT_NETIF is now DEPRECATED !!! */ + MCL_OPT_SET_NETIF_ADDR, /* specify the network interface address to */ + /* be used, NETWORK byte order. */ + /* argument: sockaddr_in or sockaddr_in6 */ + MCL_OPT_SET_NETIF_NAME, /* specify the network interface name to */ + /* be used. */ + /* argument: string (e.g. "eth0")*/ + MCL_OPT_LOOPBACK, /* will we send mcast packet to local apps */ + /* argument: int passed to setsockopt as is */ + /* + * options used by the sender + */ + MCL_OPT_TX_PROFILE, /* select a pre-defined transmission profile */ + /* argument: int (see mcl_tx_profile enum) */ + MCL_OPT_DATAGRAM_SIZE, /* datagram size */ + /* argument: int */ + MCL_OPT_TX_RATE, /* tx rate in full-sz packets/s on base layer */ + /* argument: int */ + MCL_OPT_FEC_RATIO, /* set the FEC packets ratio (n/k) (e.g. 2.0 */ + /* adds 100% of fec pkts, 3.0 adds 200% fec) */ + /* argument: float */ + MCL_OPT_REUSE_APPLI_TX_BUFFER, /* can MCL take control of appli buffer*/ + /* used to avoid an extra copy within MCL */ + /* Warning: buf must be alloc by c/re/malloc */ + /* argument: int (0 (default) or 1) */ + MCL_OPT_RESET_TRANSMISSIONS, /* delete and free all transmission */ + /* tables and the ADU list */ + /* no argument */ + MCL_OPT_SET_FEC_CODE, /* set the FEC codec to be used. If not */ + /* available, an error is returned */ + /* argument: int */ + MCL_OPT_GET_MAX_BLOCK_SIZE_FOR_CURRENT_FEC, /* retrieve the maximum */ + /* block size in bytes for current FEC code */ + /* argument: int, contains the value on return*/ + /* + * options used by the receiver + */ + MCL_OPT_IMMEDIATE_DELIVERY_TO_APPLI, /* boolean specifying if ADUs */ + /* can be delivered in arrival order (true) */ + /* or in increasing sequence number order */ + /* (false) to the receiving application */ + /* argument: int (0 (default) or 1) */ + MCL_OPT_POSTPONE_FEC_DECODING /* boolean: is FEC decoding postponed? */ + /* argument: int, 0 or 1 (default, postponed) */ +}; + +#endif /* MCL_LIB_API_NORM_H */ + diff --git a/src/norm/mcl_nack.h b/src/norm/mcl_nack.h new file mode 100644 index 0000000..08636bc --- /dev/null +++ b/src/norm/mcl_nack.h @@ -0,0 +1,108 @@ +/* $Id: mcl_nack.h,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_NACK_H +#define MCL_NACK_H + +// +// NACK request object at a source +// +class src_nack_req { + void src_nack_req (); + void ~src_nack_req (); + // process a NACK request + error_status process (); +} + + +// status returned by update_loss_status method +enum loss_recovery_status = { + LOSS_RECOVERY_STATUS_INVALID = 0, + LOSS_RECOVERY_STATUS_NO, + LOSS_RECOVERY_STATUS_YES, + LOSS_RECOVERY_STATUS_PARTIAL +}; + +// +// NACK request object at a receiver +// +class recv_nack_req { + void recv_nack_req (loss_t *loss); + void ~recv_nack_req (); + // register a NACK for future transmission to source, if the + // erasure is not recovered by that time... + nack_req_id_t register_nack_req (loss); + // remove a registered NACK request (e.g. if the erasure has + // been recovered in the mean-time) + int remove_nack_req (); + // check before sending to source if the corresponding loss(es) + // has(have) been recovered. + // returns the new status. + loss_recovery_status update_loss_status (); + // in case of LOSS_RECOVERY_STATUS_PARTIAL, update the NACK request + // before processing it... + error_status update_nack_req (); + +private: + loss_descr loss; // describes the related loss or range of + // losses for this NACK request +} + + + +/******************************************************************************/ + + +#ifdef NEVERDEF +// +// NACK processing at the source +// +class source_nack_proc { +public: +private: +} + + +// NACK request identifier in the receiver's NACK request list +typedef int nack_req_id_t + +// +// NACK processing at a receiver +// +class receiver_nack_proc { +public: + void receiver_nack_proc (void); + void ~receiver_nack_proc (void); + // register a NACK for future transmission to source, if the + // erasure is not recovered by that time... + nack_req_id_t register_nack_req (loss); + // remove a registered NACK request (e.g. if the erasure has + // been recovered in the mean-time) + int remove_nack_req (nack_req_id_t nack_id); + // + nack_req_id_t find_nack_req (loss); + +private: +} + +#endif // NEVERDEF + +#endif // MCL_NACK_H diff --git a/src/norm/mcl_node.cpp b/src/norm/mcl_node.cpp new file mode 100644 index 0000000..c1d2a40 --- /dev/null +++ b/src/norm/mcl_node.cpp @@ -0,0 +1,47 @@ +/* $Id: mcl_node.cpp,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +mcl_node::mcl_node () +{ + /* reset all stats for this node and private attributes */ + memset(this, 0, sizeof(*this)); +} + + +mcl_node::~mcl_node () +{ +} + + +mcl_error_status +mcl_node::set_id (const INT32 new_id) +{ +#ifdef DEBUG + // TODO: cross all the list to check that no other node has the + // same id... +#endif + this->id = new_id; + return MCL_OK; +} + diff --git a/src/norm/mcl_node.h b/src/norm/mcl_node.h new file mode 100644 index 0000000..3882004 --- /dev/null +++ b/src/norm/mcl_node.h @@ -0,0 +1,124 @@ +/* $Id: mcl_node.h,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_NODE_H +#define MCL_NODE_H + +/** node stats, applicable to sources and receivers. */ +typedef struct { + UINT32 xxx; +} node_stats_t; + +/** source specific stats. */ +typedef struct { + UINT32 xxx; +} source_stats_t; + +/** receiver specific stats. */ +typedef struct { + UINT32 xxx; +} receiver_stats_t; + + +/** + * Node class. + */ +class mcl_node { +public: + mcl_node (); + ~mcl_node (); + + /** + * Retrieve the node id. + * @returns < 0 if error, node id > 0 if ok + */ + INT32 get_id (void); + /** + * Set the node id. + * @param id new node id + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_id (const INT32 new_id); + + // link related functions + mcl_node *get_next (void); + mcl_node *get_prev (void); + void set_next (mcl_node *n); + void set_prev (mcl_node *p); + + // statistics + node_stats_t n_stats; // node stats + source_stats_t s_stats; // stats, may be 0 if not a source + receiver_stats_t r_stats; // stats, may be 0 if not a receiver + +private: + INT32 id; + mcl_node *prev, *next; // for linked list in class group_mgmt +}; + + +#if 0 +/** + * Member node class. + * This is a derived class from the node class. + */ +class mcl_member : public mcl_node { + mcl_member (void); + ~mcl_member (void); +}; +#endif + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline INT32 +mcl_node::get_id (void) +{ + return this->id; +} + + +inline mcl_node* +mcl_node::get_next (void) +{ + return this->next; +} + +inline mcl_node* +mcl_node::get_prev (void) +{ + return this->prev; +} + +inline void +mcl_node::set_next (mcl_node *n) +{ + this->next = n; +} + +inline void +mcl_node::set_prev (mcl_node *p) +{ + this->prev = p; +} + +#endif // MCL_NODE_H diff --git a/src/norm/mcl_norm_hdr.h b/src/norm/mcl_norm_hdr.h new file mode 100644 index 0000000..f31c721 --- /dev/null +++ b/src/norm/mcl_norm_hdr.h @@ -0,0 +1,346 @@ +/* $Id: mcl_norm_hdr.h,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_NORM_HDR_H +#define MCL_NORM_HDR_H + +#define FEC_ENCODING_ID 129 /* FEC encoding identifier */ + /* 128: small/large/expandable codes */ + /* 129: small block systematic codes */ +#define FEC_ENCODING_NAME 0 /* for Reed-Solomon (TBC) */ + +/* define to check packet integrity */ +#define MAGIC_VERSION +#ifdef MAGIC_VERSION +const UINT8 NORM_VERSION = 0xBB; +#else +const UINT8 NORM_VERSION = 0; +#endif + + +/** + * The various NORM message types + */ +enum norm_msg_type { + NORM_INVALID = 0, + NORM_INFO = 1, + NORM_DATA = 2, + NORM_CMD = 3, + NORM_NACK = 4, + NORM_ACK = 5, + NORM_REPORT = 6 +}; + + +/** + * Common part of all NORM messages + */ +typedef struct { + UINT8 version; + UINT8 type; + UINT16 seq; + UINT32 source_id; +} norm_common_hdr_t; + + +/** + * NORM_DATA header + */ +typedef struct { + UINT8 flags; + UINT8 grtt; + UINT8 gsize; + UINT8 fec_id; + + UINT16 seg_size; // max payload length for this block + UINT16 obj_size_msb; + + UINT32 obj_size_lsb; + +#if 0 + UINT16 reserved; // NON-NORM-COMPLIANT: removed +#endif + UINT16 fec_encoding_name; + + UINT16 fec_num_parity; +#if 0 + UINT16 fec_block_len; // # of data symbols in current block +#else + UINT32 fec_block_len; // NON-NORM-COMPLIANT: moved to 32 bits + // and changed meaning. Now contains the + // size in bytes of a full length block +#endif + + UINT16 obj_transp_id; // truncated object idf + UINT16 fec_symbol_id; // symbol idf (with small block FEC) + // NB: permutted for simplicity + + UINT32 fec_block_nb; // block idf + // NB: permutted for simplicity + + UINT16 payload_len; // actual length of this symbol + UINT16 offset_msb; + + UINT32 offset_lsb; +} norm_data_hdr_t; + + +/** + * NORM_INFO header + */ +typedef struct { + UINT8 flags; + UINT8 grtt; + UINT8 gsize; + UINT8 fec_id; + + UINT16 seg_size; + UINT16 obj_size_msb; + + UINT32 obj_size_lsb; + + UINT16 fec_encoding_name; + UINT16 fec_num_parity; + + UINT16 fec_block_len; + UINT16 obj_transp_id; +} norm_info_hdr_t; + + +/** + * NORM_CMD flavor definitions + */ +enum norm_cmd_flavor { + NORM_CMD_INVALID = 0, + NORM_CMD_FLUSH = 1, + NORM_CMD_SQUELCH = 2, + NORM_CMD_ACK_REQ = 3, + NORM_CMD_REPAIR_ADV = 4, + NORM_CMD_CC = 5, + NORM_CMD_APPLICATION = 6, + NORM_CMD_NO_NEW_OBJECT = 7, // NON-NORM-COMPLIANT command + NORM_CMD_CLOSE = 8 // NON-NORM-COMPLIANT command +}; + + +/** + * NORM_CMD common header + */ +typedef struct { + UINT8 grtt; + UINT8 gsize; + UINT8 flavor; + UINT8 reserved; +} norm_cmd_common_hdr_t; + + +/** + * NORM_CMD(FLUSH) header + */ +const UINT8 NORM_CMD_FLUSH_FLAG_EOT = 0x01; + +typedef struct { + UINT8 grtt; + UINT8 gsize; + UINT8 flavor; + UINT8 flags; + + UINT16 obj_transp_id; + UINT16 fec_symbol_id; // NB: permutted for simplicity + + UINT32 fec_block_nb; // NB: permutted for simplicity +} norm_cmd_flush_hdr_t; + + +/** + * NORM_CMD(SQUELCH) header + */ +typedef struct { +} norm_cmd_squelch_hdr_t; + + +/** + * NORM_CMD(ACK_REQ) header + */ +typedef struct { +} norm_cmd_ack_req_hdr_t; + + +/** + * NORM_CMD(ACK_REQ(WATERMARK)) header + */ +typedef struct { +} norm_cmd_watermark_hdr_t; + + +/** + * NORM_CMD(ACK_REQ(RTT)) header + */ +typedef struct { +} norm_cmd_ack_req_rtt_hdr_t; + + +/** + * NORM_CMD(REPAIR_ADV) header + */ +typedef struct { + UINT8 grtt; + UINT8 gsize; + UINT8 flavor; + UINT8 flags; +} norm_cmd_repair_adv_hdr_t; + + +/** + * NORM_CMD(CC) header + */ +typedef struct { +} norm_cmd_cc_hdr_t; + + +/** + * NORM_CMD(APPLICATION) header + */ +typedef struct { +} norm_cmd_application_hdr_t; + + +/* start of NON-NORM-COMPLIANT extensions { */ + +/** + * NORM_CMD(NO_NEW_OBJECT) header + * Informs receivers of all the objects that are being sent in this session + * by this sender. + * NON-NORM-COMPLIANT command + */ +typedef struct { + UINT8 grtt; + UINT8 gsize; + UINT8 flavor; // NORM_CMD_NO_NEW_OBJECT + UINT8 reserved; // must be 0'ed + + UINT32 max_object_id; +} norm_cmd_no_new_object_hdr_t; + +/** + * NORM_CMD(CLOSE) header + * Informs receivers that this sender leaves immediately the NORM session. + * This is a non-gracefull close. + * NON-NORM-COMPLIANT command + */ +typedef struct { + UINT8 grtt; + UINT8 gsize; + UINT8 flavor; // NORM_CMD_CLOSE + UINT8 reserved; // must be 0'ed +} norm_cmd_close_hdr_t; + + +/* } end of NON-NORM-COMPLIANT extensions */ + + +/****** NACK stuff ******/ + + +/** + * NORM_NACK header + */ +typedef struct { + UINT32 server_id; + + UINT32 grtt_response_sec; + + UINT32 grtt_response_usec; + + UINT16 loss_estimate; + UINT16 grtt_req_seq; +} norm_nack_hdr_t; + + +/** + * NORM_NACK content can have one of the following forms + */ +enum norm_nack_form { + NORM_NACK_ITEMS = 1, + NORM_NACK_RANGES, + NORM_NACK_ERASURES +}; + +/** + * NORM_NACK flags + */ +enum norm_nack_flags { + NORM_NACK_SEGMENT = 0x01, + NORM_NACK_BLOCK = 0x02, + NORM_NACK_INFO = 0x04, + NORM_NACK_OBJECT = 0x08 +}; + + +/** + * NORM_NACK content header + */ +typedef struct { + UINT8 form; + UINT8 flags; + UINT16 length; + + UINT16 obj_transp_id; + UINT16 fec_symbol_id_or_erasure_count; // NB: permutted for simplicity + + UINT32 fec_block_nb; // NB: permutted for simplicity +} norm_nack_content_hdr_t; + + +/****** end of NACK stuff ******/ + + +/** + * NORM_ACK common header + */ +typedef struct { + UINT32 server_id; + + UINT32 grtt_response_sec; + + UINT32 grtt_response_usec; + + UINT16 loss_estimate; + UINT16 grtt_req_seq; + + UINT8 ack_flavor; + UINT8 reserved1; + UINT16 reserved2; +} norm_ack_hdr_t; + + +/** + * NORM_ACK(WATERMARK) ACK content header + */ +typedef struct { + UINT16 obj_transp_id; + UINT16 fec_symbol_id; // NB: permutted for simplicity + + UINT32 fec_block_nb; // NB: permutted for simplicity +} norm_ack_watermark_hdr_t; + + +#endif // MCL_NORM_HDR_H diff --git a/src/norm/mcl_norm_pkt_mgmt.cpp b/src/norm/mcl_norm_pkt_mgmt.cpp new file mode 100644 index 0000000..30c4b59 --- /dev/null +++ b/src/norm/mcl_norm_pkt_mgmt.cpp @@ -0,0 +1,601 @@ +/* $Id: mcl_norm_pkt_mgmt.cpp,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * Default constructor. + */ +mcl_norm_pkt_mgmt::mcl_norm_pkt_mgmt () +{ +} + + +/** + * Default destructor. + */ +mcl_norm_pkt_mgmt::~mcl_norm_pkt_mgmt () +{ +} + + +/****** sender specific sending methods ***************************************/ + + +/** + * Macro to fill in the NORM common header. + * Assumes the presence of variables: + * mcl_cb *mclcb; + * norm_common_hdr_t *c_hdr; + */ +#define FILL_NORM_COMMON_HDR(t) \ + c_hdr = (norm_common_hdr_t*)(this->hdr_buffer); \ + c_hdr->version = NORM_VERSION; \ + c_hdr->type = t; \ + c_hdr->seq = htons(mclcb->tx.get_next_norm_pkt_seq()); \ + c_hdr->source_id = htonl(mclcb->node.get_id()); + + +/** + * Creates a data packet, allocating and initializing the NORM header. + * Used by the sender. + * Only the header is initialized, the data buffer is left untouched. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @param mclcb + * @param du the data unit to send + * @param hdr pointer to header pointer updated when leaving this function + * @return the header length or <= 0 in case of error + */ +INT32 +mcl_norm_pkt_mgmt::create_data_hdr (mcl_cb *const mclcb, + mcl_du *const du, + norm_common_hdr_t **hdr) +{ + norm_common_hdr_t *c_hdr; // common header part + norm_data_hdr_t *d_hdr; // NORM_DATA header part + mcl_block *blk; + mcl_adu *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_norm_pkt_mgmt::create_data_hdr:\n")) + /* + * common part + */ + FILL_NORM_COMMON_HDR(NORM_DATA); + /* + * specific part + */ + ASSERT(du); + blk = du->block; + ASSERT(blk); + adu = blk->adu; + ASSERT(adu); + + d_hdr = (norm_data_hdr_t*)(c_hdr + 1); + + d_hdr->flags = 0; + d_hdr->grtt = 0; + d_hdr->gsize = 0; + d_hdr->fec_id = FEC_ENCODING_ID; + + d_hdr->seg_size = htons(du->len); + d_hdr->obj_size_msb = htons(0); + + d_hdr->obj_size_lsb = htonl(adu->get_len()); + +#if 0 + d_hdr->reserved = htons(0); +#else + /* NON-NORM-COMPLIANT: removed */ +#endif + d_hdr->fec_encoding_name = htons(FEC_ENCODING_NAME); + + /* max number of FEC that can be generated for this block */ + d_hdr->fec_num_parity = htons(mclcb->fec.get_n() - mclcb->fec.get_k()); +#if 0 + /* actual nb of DUs for this block (may be < k for last blk) */ + d_hdr->fec_block_len = htons((UINT16)(blk->du_nb)); +#else + /* NON-NORM-COMPLIANT: moved to 32 bits and changed meaning */ + d_hdr->fec_block_len = htonl((UINT32)(adu->get_full_size_block_len())); +#endif + + d_hdr->obj_transp_id = htons((UINT16)(adu->get_seq())); +#if 0 + d_hdr->fec_symbol_id = htons((UINT16)(du->seq)); +#else + /* NON-NORM-COMPLIANT: add a FEC flag */ + d_hdr->fec_symbol_id = htons((UINT16)(du->seq | (du->is_fec ? 0x8000 : 0))); +#endif + + d_hdr->fec_block_nb = htonl((UINT32)(blk->seq)); + + d_hdr->payload_len = htons(du->len); + d_hdr->offset_msb = htons(0); + + d_hdr->offset_lsb = htons(0); // NOT USED... + + *hdr = c_hdr; + TRACELVL(5, (mcl_stdout, "<- mcl_norm_pkt_mgmt::create_data_hdr:\n")) + return (sizeof(norm_common_hdr_t) + sizeof(norm_data_hdr_t)); +} + + +/** + * Create a NORM_CMD(FLUSH) header. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @return the header length or <= 0 in case of error + */ +INT32 +mcl_norm_pkt_mgmt::create_cmd_flush_hdr (mcl_cb *const mclcb, + norm_common_hdr_t **hdr, + mcl_du *du) +{ + norm_common_hdr_t *c_hdr; // common header part + norm_cmd_flush_hdr_t *f_hdr; // NORM_CMD_FLUSH header + mcl_block *blk; + mcl_adu *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_norm_pkt_mgmt::create_cmd_flush_hdr:\n")) + /* + * common part + */ + FILL_NORM_COMMON_HDR(NORM_CMD); + /* + * specific part + */ + ASSERT(du); + blk = du->block; + ASSERT(blk); + adu = blk->adu; + ASSERT(adu); + + f_hdr = (norm_cmd_flush_hdr_t*)(c_hdr + 1); + f_hdr->grtt = 0; + f_hdr->gsize = 0; + f_hdr->flavor = NORM_CMD_FLUSH; + f_hdr->flags = NORM_CMD_FLUSH_FLAG_EOT; + + f_hdr->obj_transp_id = htons((UINT16)(adu->get_seq())); +#if 0 + f_hdr->fec_symbol_id = htons((UINT16)(du->seq)); +#else + /* NON-NORM-COMPLIANT: add a FEC flag */ + f_hdr->fec_symbol_id = htons((UINT16)(du->seq | (du->is_fec ? 0x8000 : 0))); +#endif + + f_hdr->fec_block_nb = htonl((UINT32)(blk->seq)); + + *hdr = c_hdr; + TRACELVL(5, (mcl_stdout, "<- mcl_norm_pkt_mgmt::create_cmd_flush_hdr:\n")) + return (sizeof(norm_common_hdr_t) + sizeof(norm_cmd_flush_hdr_t)); +} + + +/** + * Create a NORM_CMD(NO_NEW_OBJECT) header. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @return the header length or <= 0 in case of error + */ +INT32 +mcl_norm_pkt_mgmt::create_cmd_no_new_object_hdr (mcl_cb *const mclcb, + norm_common_hdr_t **hdr) +{ + norm_common_hdr_t *c_hdr; // common header part + norm_cmd_no_new_object_hdr_t *nno_hdr; // NORM_CMD_NO_NEW_OBJECT header + + TRACELVL(5, (mcl_stdout, "-> mcl_norm_pkt_mgmt::create_cmd_no_new_object_hdr:\n")) + /* + * common part + */ + FILL_NORM_COMMON_HDR(NORM_CMD); + /* + * specific part + */ + nno_hdr = (norm_cmd_no_new_object_hdr_t*)(c_hdr + 1); + nno_hdr->grtt = 0; + nno_hdr->gsize = 0; + nno_hdr->flavor = NORM_CMD_NO_NEW_OBJECT; + nno_hdr->reserved = 0; + + nno_hdr->max_object_id = htonl(mclcb->tx.get_highest_submitted_adu_seq()); + + *hdr = c_hdr; + TRACELVL(5, (mcl_stdout, "<- mcl_norm_pkt_mgmt::create_cmd_no_new_object_hdr:\n")) + return (sizeof(norm_common_hdr_t) + sizeof(norm_cmd_no_new_object_hdr_t)); +} + + +/** + * Create a NORM_CMD(CLOSE) header. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @return the header length or <= 0 in case of error + */ +INT32 +mcl_norm_pkt_mgmt::create_cmd_close_hdr (mcl_cb *const mclcb, + norm_common_hdr_t **hdr) +{ + norm_common_hdr_t *c_hdr; // common header part + norm_cmd_close_hdr_t *close_hdr; // NORM_CMD_CLOSE header part + + TRACELVL(5, (mcl_stdout, "-> mcl_norm_pkt_mgmt::create_cmd_close_hdr:\n")) + /* + * common part + */ + FILL_NORM_COMMON_HDR(NORM_CMD); + /* + * specific part + */ + close_hdr = (norm_cmd_close_hdr_t*)(c_hdr + 1); + close_hdr->grtt = 0; + close_hdr->gsize = 0; + close_hdr->flavor = NORM_CMD_CLOSE; + close_hdr->reserved = 0; + + *hdr = c_hdr; + TRACELVL(5, (mcl_stdout, "<- mcl_norm_pkt_mgmt::create_cmd_close_hdr:\n")) + return (sizeof(norm_common_hdr_t) + sizeof(norm_cmd_close_hdr_t)); +} + + +/****** sender specific parsing methods ***************************************/ + + +/** + * Parses the specific header of a NORM-NACK packet, performs some checks, + * and initializes the info structure accordingly. + * Used by the sender. + * After calling this function, call get_next_nack_content_block() to + * get all the NACK content blocks of the packet. + * @param mclcb + * @param pkt pointer to the received packet + * @param infos pointer to the info struct that is updated by this + * function + * @param + * @return completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_norm_pkt_mgmt::parse_nack_hdr (mcl_cb *const mclcb, + mcl_rx_pkt *pkt, + mcl_data_hdr_infos_t *infos) +{ + norm_nack_hdr_t *n_hdr; + + TRACELVL(5, (mcl_stdout, "-> mcl_norm_pkt_mgmt::parse_nack_hdr:\n")) + /* + * quick check on packet length; must at least contain the + * norm_common + data headers + */ + if (pkt->pkt_len < (INT32)sizeof(norm_common_hdr_t) + + (INT32)sizeof(norm_nack_hdr_t) + + (INT32)sizeof(norm_nack_content_hdr_t)) { + PRINT_ERR((mcl_stderr, + "mcl_norm_pkt_mgmt::parse_nack_hdr: ERROR, too short (at least %d expected, got %d)\n", + (INT32)sizeof(norm_common_hdr_t) + + (INT32)sizeof(norm_data_hdr_t) + + (INT32)sizeof(norm_nack_content_hdr_t), pkt->pkt_len)) + return MCL_ERROR; + } + /* + * content processing + */ + n_hdr = (norm_nack_hdr_t*)(pkt->get_buf() + sizeof(norm_common_hdr_t)); + infos->server_id = ntohl(n_hdr->server_id); + infos->grtt_sec = ntohl(n_hdr->grtt_response_sec); + infos->grtt_usec = ntohl(n_hdr->grtt_response_usec); + infos->loss_estimate = ntohs(n_hdr->loss_estimate); + infos->grtt_req_seq = ntohs(n_hdr->grtt_req_seq); + /* + * remember position of the first norm_nack_content_hdr_t block + */ + this->next_nack_content_ptr = (norm_nack_content_hdr_t*)(n_hdr + 1); + TRACELVL(5, (mcl_stdout, "<- mcl_norm_pkt_mgmt::parse_nack_hdr: ok\n")) + return MCL_OK; +} + + +/** + * Return the following norm_nack_content_hdr_t block of packet. + * Requires calling parse_nack_hdr() first. + * @return completion status (MCL_OK or MCL_ERROR). + */ +norm_nack_content_hdr_t * +mcl_norm_pkt_mgmt::get_next_nack_content_block (mcl_cb *const mclcb, + class mcl_rx_pkt *pkt) +{ + norm_nack_content_hdr_t *nc; + + if (this->next_nack_content_ptr == NULL) + return NULL; + /* + * process the following NACK content block, i.e. move all + * values into host format. + */ + // TODO: perform block length check + nc = next_nack_content_ptr; + nc->length = ntohs(nc->length); + nc->obj_transp_id = ntohs(nc->obj_transp_id); + nc->fec_symbol_id_or_erasure_count = ntohs(nc->fec_symbol_id_or_erasure_count); + nc->fec_block_nb = ntohl(nc->fec_block_nb); + + /* NB: assume there is a single content block! */ + // TODO: support of more than a single block... + this->next_nack_content_ptr = NULL; + return nc; +} + + + +/****** receiver specific parsing methods *************************************/ + + +/** + * Parses the common header of a NORM packet, performs some checks, + * and initializes the info structure accordingly. + * Used by the receiver. + * @param mclcb + * @param pkt pointer to the received packet + * @param infos pointer to the info struct that is updated by this + * function + * @return completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_norm_pkt_mgmt::parse_common_hdr (mcl_cb *const mclcb, + mcl_rx_pkt *pkt, + mcl_common_hdr_infos_t *infos) +{ + norm_common_hdr_t *c_hdr; + + TRACELVL(5, (mcl_stdout, "-> mcl_norm_pkt_mgmt::parse_common_hdr:\n")) + /* + * quick check on packet length; must at least contain the + * common header + */ + if (pkt->pkt_len < (INT32)(sizeof(norm_common_hdr_t))) { + PRINT_ERR((mcl_stderr, + "mcl_rx::parse_common_hdr: ERROR, too short (at least %d expected, got %d)\n", + (INT32)sizeof(norm_common_hdr_t), pkt->pkt_len)) + return MCL_ERROR; + } + c_hdr = (norm_common_hdr_t*)(pkt->get_buf()); + if ((c_hdr->version) != NORM_VERSION) { + PRINT_ERR((mcl_stderr, + "mcl_rx::parse_common_hdr: ERROR, bad version (%d expected, got %d)\n", + NORM_VERSION, c_hdr->version)) + return MCL_ERROR; + } + infos->type = c_hdr->type; + infos->seq = ntohs(c_hdr->seq); + infos->source_id = ntohl(c_hdr->source_id); + TRACELVL(5, (mcl_stdout, "<- mcl_norm_pkt_mgmt::parse_common_hdr:\n")) + return MCL_OK; +} + + +/** + * Parses the specific header of a NORM-DATA packet, performs some checks, + * and initializes the info structure accordingly. + * Used by the receiver. + * @param mclcb + * @param pkt pointer to the received packet + * @param infos pointer to the info struct that is updated by this + * function + * @return completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_norm_pkt_mgmt::parse_data_hdr (mcl_cb *const mclcb, + mcl_rx_pkt *pkt, + mcl_data_hdr_infos_t *infos) +{ + norm_data_hdr_t *d_hdr; + + TRACELVL(5, (mcl_stdout, "-> mcl_norm_pkt_mgmt::parse_data_hdr:\n")) + /* + * quick check on packet length; must at least contain the + * norm_common + data headers + */ + if (pkt->pkt_len < (INT32)sizeof(norm_common_hdr_t) + (INT32)sizeof(norm_data_hdr_t)) { + PRINT_ERR((mcl_stderr, + "mcl_norm_pkt_mgmt::parse_data_hdr: ERROR, too short (at least %d expected, got %d)\n", + (INT32)sizeof(norm_common_hdr_t) + + (INT32)sizeof(norm_data_hdr_t), pkt->pkt_len)) + return MCL_ERROR; + } + d_hdr = (norm_data_hdr_t*)(pkt->get_buf() + sizeof(norm_common_hdr_t)); + infos->flags = d_hdr->flags; + infos->idf_adu = ntohs(d_hdr->obj_transp_id); + infos->idf_block = ntohl(d_hdr->fec_block_nb); + infos->idf_du = ntohs(d_hdr->fec_symbol_id); + infos->du_len = ntohs(d_hdr->payload_len); + infos->adu_len = ntohl(d_hdr->obj_size_lsb); + /* NON-NORM-COMPLIANT: block_len is full-size block length in bytes */ + //infos->block_len = ntohs(d_hdr->fec_block_len); + infos->block_len = ntohl(d_hdr->fec_block_len); +#if 0 + infos->is_fec = (infos->idf_du < infos->block_len) ? false : true; +#else + /* NON-NORM-COMPLIANT: use a FEC flag in the symbol idf instead */ + infos->is_fec = (infos->idf_du & 0x8000 ? true : false); + infos->idf_du = (infos->idf_du & 0x7FFF); /* FEC flag removed! */ +#endif +#if 0 + TRACE(("mcl_norm_pkt_mgmt::parse_data_hdr: is_fec=%d, idf_du=%d, block_len=%d\n", + infos->is_fec, infos->idf_du, infos->block_len)) +#endif + /* + * perform some field checking now... + */ + if (infos->adu_len == 0) { + PRINT_ERR((mcl_stderr, + "mcl_norm_pkt_mgmt::parse_data_hdr: ERROR, bad adu_len field (got %d)\n", + infos->adu_len)) + return MCL_ERROR; + } +#if 0 + if (infos->block_len == 0 || (INT32)infos->block_len >= mclcb->fec.get_max_k()) { + PRINT_ERR((mcl_stderr, + "mcl_norm_pkt_mgmt::parse_data_hdr: ERROR, bad block_len field (got %d, should be [0;%d[)\n", + infos->block_len, mclcb->fec.get_max_k())) + return MCL_ERROR; + } +#else + if (infos->block_len == 0 || + (INT32)infos->block_len >= mclcb->fec.get_max_k() * mclcb->get_payload_size()) { + PRINT_ERR((mcl_stderr, + "mcl_norm_pkt_mgmt::parse_data_hdr: ERROR, bad block_len field (got %d, should be [0;%d[)\n", + infos->block_len, + mclcb->fec.get_max_k() * mclcb->get_payload_size())) + return MCL_ERROR; + } +#endif + TRACELVL(5, (mcl_stdout, "<- mcl_norm_pkt_mgmt::parse_data_hdr: ok\n")) + return MCL_OK; +} + + +/** + * Parses the specific header of a NORM_CMD packet, performs some checks, + * and initializes the info structure accordingly. + * Used by the receiver. + * @param mclcb + * @param pkt pointer to the received packet + * @param infos pointer to the info struct that is updated by this + * function + * @return completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_norm_pkt_mgmt::parse_cmd_hdr (mcl_cb *const mclcb, + mcl_rx_pkt *pkt, + mcl_data_hdr_infos_t *infos) +{ + norm_cmd_common_hdr_t *cmd_hdr; + + TRACELVL(5, (mcl_stdout, "-> mcl_norm_pkt_mgmt::parse_cmd_hdr:\n")) + /* + * quick check on packet length; must at least contain the + * norm_common + cmd_common headers + */ + if (pkt->pkt_len < (INT32)sizeof(norm_common_hdr_t) + (INT32)sizeof(norm_cmd_common_hdr_t)) { + PRINT_ERR((mcl_stderr, + "mcl_norm_pkt_mgmt::parse_cmd_hdr: ERROR, too short (at least %d expected, got %d)\n", + (INT32)sizeof(norm_common_hdr_t) + + (INT32)sizeof(norm_cmd_common_hdr_t), pkt->pkt_len)) + return MCL_ERROR; + } + cmd_hdr = (norm_cmd_common_hdr_t*)(pkt->get_buf() + sizeof(norm_common_hdr_t)); + infos->cmd_flavor = (norm_cmd_flavor)cmd_hdr->flavor; + + switch (infos->cmd_flavor) { + case NORM_CMD_FLUSH: + norm_cmd_flush_hdr_t *f_hdr; + + f_hdr = (norm_cmd_flush_hdr_t*)cmd_hdr; + infos->idf_adu = ntohs(f_hdr->obj_transp_id); + infos->idf_block = ntohl(f_hdr->fec_block_nb); + infos->idf_du = 0; // not used even if it's available + infos->is_fec = false; // not used even if it's available + TRACELVL(5, (mcl_stdout, + " mcl_norm_pkt_mgmt::parse_cmd_hdr: NORM_CMD_FLUSH rcvd\n")) + break; + + case NORM_CMD_NO_NEW_OBJECT: + infos->max_idf_adu = ntohl(((norm_cmd_no_new_object_hdr_t*)cmd_hdr)->max_object_id); + TRACELVL(5, (mcl_stdout, + " mcl_norm_pkt_mgmt::parse_cmd_hdr: NORM_CMD_NO_NEW_OBJECT rcvd, adu_idf range is [0; %d]\n", + infos->max_idf_adu)) + break; + case NORM_CMD_CLOSE: + /* nothing to do for the present */ + TRACELVL(5, (mcl_stdout, + " mcl_norm_pkt_mgmt::parse_cmd_hdr: NORM_CMD_CLOSE rcvd\n")) + break; + default: + PRINT_ERR((mcl_stderr, + "mcl_norm_pkt_mgmt::parse_cmd_hdr: ERROR, NORM_CMD flavor %d not supported\n", + infos->cmd_flavor)) + return MCL_ERROR; + } + TRACELVL(5, (mcl_stdout, "<- mcl_norm_pkt_mgmt::parse_cmd_hdr: ok\n")) + return MCL_OK; +} + + +/****** receiver specific sending methods *************************************/ + +/** + * Create a NORM_NACK header. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @return the header length or <= 0 in case of error + */ +INT32 +mcl_norm_pkt_mgmt::create_nack_hdr (mcl_cb *const mclcb, + norm_common_hdr_t **hdr, + UINT32 adu_id, + UINT32 blk_id, + INT32 missing) +{ + norm_common_hdr_t *c_hdr; // common header part + norm_nack_hdr_t *n_hdr; // NORM_NACK header + norm_nack_content_hdr_t *nc_hdr; // NORM_NACK content header + + TRACELVL(5, (mcl_stdout, "-> mcl_norm_pkt_mgmt::create_nack_hdr:\n")) + /* + * common part + */ + FILL_NORM_COMMON_HDR(NORM_NACK); + /* + * specific part + */ + ASSERT(missing > 0); + n_hdr = (norm_nack_hdr_t*)(c_hdr + 1); + n_hdr->server_id = 0; // TODO + n_hdr->grtt_response_sec = 0; // TODO + n_hdr->grtt_response_sec = 0; // TODO + n_hdr->loss_estimate = 0; // TODO + n_hdr->grtt_req_seq = 0; // TODO + /* + * fill in the nack content now + * only supports the "ask for additional FEC for this block" version + */ + nc_hdr = (norm_nack_content_hdr_t*)(n_hdr + 1); + nc_hdr->form = NORM_NACK_ERASURES; + nc_hdr->flags = NORM_NACK_BLOCK; + nc_hdr->obj_transp_id = htons((UINT16)adu_id); + nc_hdr->fec_symbol_id_or_erasure_count = htons(missing); + nc_hdr->fec_block_nb = htonl((UINT32)blk_id); + + *hdr = c_hdr; + TRACELVL(5, (mcl_stdout, "<- mcl_norm_pkt_mgmt::create_nack_hdr:\n")) + return (sizeof(norm_common_hdr_t) + sizeof(norm_nack_hdr_t) + + sizeof(norm_nack_content_hdr_t)); +} + + diff --git a/src/norm/mcl_norm_pkt_mgmt.h b/src/norm/mcl_norm_pkt_mgmt.h new file mode 100644 index 0000000..9a364a6 --- /dev/null +++ b/src/norm/mcl_norm_pkt_mgmt.h @@ -0,0 +1,277 @@ +/* $Id: mcl_norm_pkt_mgmt.h,v 1.2 2004/01/30 16:27:42 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_NORM_PKT_MGMT_H +#define MCL_NORM_PKT_MGMT_H + +/** + * Struct used to store common header information + */ +typedef struct { + INT32 type; + UINT16 seq; + UINT32 source_id; +} mcl_common_hdr_infos_t; + + +/** + * Struct used to store data header information + */ +typedef struct mcl_data_hdr_infos { + /* + * data related fields + */ + UINT32 flags; + UINT32 idf_adu; // ADU identifier + UINT32 idf_block; // BLOCK identifier + UINT32 idf_du; // DU identifier + UINT32 is_fec; // 1 if DU has FEC content + UINT32 du_len; + //UINT32 demux_label; // demux label, also known as TSI + UINT32 codepoint; // codepoint + // fields used by FTI (FEC object tx info) (previously NEWADU) + UINT32 adu_len; // ADU length in bytes + UINT32 block_len; // full-sized block length in bytes + //UINT32 block_du_nb; // full-sized block length in # of DUs (k) + + /* + * NORM_CMD specific fields + */ + norm_cmd_flavor cmd_flavor; // type of command or NORM_CMD_INVALID + // fields used by NONEWADU + UINT32 max_idf_adu; // highest ADU identifier in session + // fields used by CLOSE + UINT32 close; // CLOSE sig: boolean + + /* + * NORM_NACK specific flags + */ + UINT32 server_id; + UINT32 grtt_sec; + UINT32 grtt_usec; + UINT32 loss_estimate; + UINT32 grtt_req_seq; +} mcl_data_hdr_infos_t; + + +/** + * enumeration of the various signaling types supported. + * these types are in fact mapped onto the NORM signaling types. + */ +enum mcl_sig_types { + MCL_SIG_NEWADU = 0, + MCL_SIG_NONEWADU, + MCL_SIG_CLOSE +}; + + +/** + * This class provides all the required functions to create and analyze + * NORM packets. + * One instance per session. + */ +class mcl_norm_pkt_mgmt { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + mcl_norm_pkt_mgmt (); + + /** + * Default destructor. + */ + ~mcl_norm_pkt_mgmt (); + + /****** sender specific sending methods *******************************/ + + /** + * Creates a data packet, allocating and initializing the NORM header. + * Used by the sender. + * Only the header is initialized, the data buffer is left untouched. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @param mclcb + * @param du the data unit to send + * @param chdr pointer to header pointer updated when leaving this + * function + * @return the header length or <= 0 in case of error + */ + INT32 create_data_hdr (mcl_cb *const mclcb, + mcl_du *const du, + norm_common_hdr_t **hdr); + + /** + * Create a NORM_CMD(FLUSH) header. + * Used by the sender. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @return the header length or <= 0 in case of error + */ + + INT32 create_cmd_flush_hdr (mcl_cb *const mclcb, + norm_common_hdr_t **hdr, + mcl_du *du); + + /** + * Create a NORM_CMD(NO_NEW_OBJECT) header. + * Used by the sender. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @return the header length or <= 0 in case of error + */ + INT32 create_cmd_no_new_object_hdr (mcl_cb *const mclcb, + norm_common_hdr_t **hdr); + + /** + * Create a NORM_CMD(CLOSE) header. + * Used by the sender. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @return the header length or <= 0 in case of error + */ + INT32 create_cmd_close_hdr (mcl_cb *const mclcb, + norm_common_hdr_t **hdr); + + /****** sender specific parsing methods *******************************/ + + /** + * Parses the specific header of a NORM-NACK packet, performs some + * checks, and initializes the info structure accordingly. + * Used by the sender. + * After calling this function, call get_next_nack_content_block() to + * get all the NACK content blocks of the packet. + * @param mclcb + * @param pkt pointer to the received packet + * @param infos pointer to the info struct that is updated by this + * function + * @param + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status parse_nack_hdr (mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_data_hdr_infos_t *infos); + + /** + * Return the following norm_nack_content_hdr_t block of packet. + * Requires calling parse_nack_hdr() first. + * @return completion status (MCL_OK or MCL_ERROR). + */ + norm_nack_content_hdr_t *get_next_nack_content_block + (mcl_cb *const mclcb, + class mcl_rx_pkt *pkt); + + /****** receiver specific parsing methods *****************************/ + + /** + * Parses the common header of any NORM packet, performs some checks + * and initializes the info structure accordingly. + * Used by the receiver. + * @param mclcb + * @param pkt pointer to the received packet + * @param infos pointer to the info struct that is updated by this + * function + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status parse_common_hdr (mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_common_hdr_infos_t *infos); + + /** + * Parses the specific header of a NORM-DATA packet, performs some + * checks and initializes the info structure accordingly. + * Used by the receiver. + * @param mclcb + * @param pkt pointer to the received packet + * @param infos pointer to the info struct that is updated by this + * function + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status parse_data_hdr (mcl_cb *const mclcb, + mcl_rx_pkt *pkt, + mcl_data_hdr_infos_t *infos); + + /** + * Parses the specific header of a NORM_CMD packet, performs some + * checks and initializes the info structure accordingly. + * Used by the receiver. + * @param mclcb + * @param pkt pointer to the received packet + * @param infos pointer to the info struct that is updated by this + * function + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status parse_cmd_hdr (mcl_cb *const mclcb, + mcl_rx_pkt *pkt, + mcl_data_hdr_infos_t *infos); + + /****** receiver specific sending methods *****************************/ + + /** + * Create a NORM_NACK header. + * Used by the receiver. + * The buffer containing the header is statically assigned, and will + * be reused at the next call to this member function, so please use + * it immediately... + * @return the header length or <= 0 in case of error + */ + INT32 + mcl_norm_pkt_mgmt::create_nack_hdr (mcl_cb *const mclcb, + norm_common_hdr_t **hdr, + UINT32 adu_id, + UINT32 blk_id, + INT32 missing); + + + /****** Public Attributes *********************************************/ + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + /** + * Maximum header size. + * Equal to the maximum datagram size (e.g. a signaling pkt) + */ + static const INT32 MCL_MAX_HDR_SIZE = 1500; + + /** Static buffer used to store the packet header just created. */ + char hdr_buffer[MCL_MAX_HDR_SIZE]; + + /** + * Pointer used by get_next_nack_content_block(). + * Used to iterate on the various NACK content blocks of a NACK. + * Used by the sender. + */ + norm_nack_content_hdr_t *next_nack_content_ptr; +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +#endif // !MCL_NORM_PKT_MGMT_H diff --git a/src/norm/mcl_periodic_proc.cpp b/src/norm/mcl_periodic_proc.cpp new file mode 100644 index 0000000..8a15192 --- /dev/null +++ b/src/norm/mcl_periodic_proc.cpp @@ -0,0 +1,215 @@ +/* $Id: mcl_periodic_proc.cpp,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +mcl_periodic_proc::mcl_periodic_proc () +{ + /** Time_count of last do_periodic_proc call. */ + this->last_periodic_proc_tc = 0; + /** itimer of last do_periodic_proc call. */ + this->last_periodic_proc_it = 0; + /** fractional tick_nb in do_periodic_proc. */ + this->remaining_tx_tick_nb = 0.0; +} + + +mcl_periodic_proc::~mcl_periodic_proc () +{ +} + + +void +mcl_periodic_proc::scan_all_sessions (void) +{ + INT32 ses; // session id + mcl_cb *mclcb; // session control block +#ifdef GET_SYSINFO + mcl_cb *mclcb_tmp = NULL;/* remember a valid mclcb */ + int mcl_sysinfo_count = MCL_SYSINFO_PERIOD / MCL_PERIODIC_TIMER_PERIOD; +#endif + + /* + * scan all the sessions + */ + for (ses = 0; ses < MAX_NB_MCLCB; ses++) { + if ((mclcb = mclcb_tab[ses]) == NULL) + continue; /* unused entry! */ + mclcb->lock(); + if (!mclcb->is_fully_initialized()) { + mclcb->unlock(); + continue; + } + TRACELVL(6, (mcl_stdout, "mcl_periodic_proc::scan_all_sessions: time_count=%d, ses=%d, states=%s/%s\n", + mcl_time_count, ses, + mclcb->fsm.print_tx_state(mclcb), + mclcb->fsm.print_rx_state(mclcb))) + /* everything is done here... */ + mclcb->periodic_proc.do_periodic_proc(mclcb); +#ifdef GET_SYSINFO + mclcb_tmp = mclcb; /* remember for GET_SYSINFO needs */ +#endif + mclcb->unlock(); + } +#ifdef GET_SYSINFO + /* + * print system information if required + * precise timing is not required here... + */ + if (mclcb_tmp && mclcb_tmp->verbose == 2 && --mcl_sysinfo_count == 0) { + /* one trace every approx. MCL_SYSINFO_PERIOD usec */ + mcl_print_sysinfo(mclcb_tmp); + mcl_sysinfo_count = MCL_SYSINFO_PERIOD / MCL_PERIODIC_TIMER_PERIOD; + } +#endif /* GET_SYSINFO */ +} + + +void +mcl_periodic_proc::do_periodic_proc (mcl_cb *mclcb) +{ + //mcl_periodic_timer_var *timer_var; // class containing per session var + mcl_itime_t now; /* current itime */ + mcl_itime_t elit; /* elasped itime since last call */ + int eltc; /* elasped time_count since last call */ + float true_tx_tick_nb;/* tx tick elapsed as a float */ + int tx_tick_nb; /* integral part of true_tx_tick_nb */ + + ASSERT(mclcb->is_fully_initialized()); + TRACELVL(5, (mcl_stdout, "-> mcl_periodic_proc::mcl_do_periodic_proc: mclcb=x%x\n", (int)mclcb)) + + //timer_var = &(mclcb->periodic_timer_var); + now = mcl_get_itime(); + //if (timer_var->last_periodic_proc_tc == 0) + if (this->last_periodic_proc_tc == 0) { + /* first call for this mclcb => timing initialization */ + this->last_periodic_proc_it = now; + this->last_periodic_proc_tc = mcl_time_count; + this->remaining_tx_tick_nb = 0.0; + } + /* + * elapsed time + */ + elit = mcl_itime_sub(now, this->last_periodic_proc_it); + this->last_periodic_proc_it = now; + /* + * elapsed time_count since last call + * NB: no fractional part here, done in mcl_timer_thread + */ + eltc = mcl_time_count - this->last_periodic_proc_tc; + this->last_periodic_proc_tc = mcl_time_count; + + /* + * periodic transmissions + */ + if (mclcb->is_a_sender()) { + /* + * how many tx ticks since last call? + * first calculate the float tick nb, then its integral part, + * and remember the decimal part for next time + */ + true_tx_tick_nb = (float) + (mcl_it2sec(elit) / mcl_periodic_timer::get_period() + + this->remaining_tx_tick_nb); + tx_tick_nb = (int)(true_tx_tick_nb); + this->remaining_tx_tick_nb = true_tx_tick_nb - (float)tx_tick_nb; + if (mcl_periodic_timer::must_reduce_activity()) { + /* + * when in "no_time_to_sleep" mode, limit the + * tx_tick_nb to try to solve the problem... + */ + tx_tick_nb = 1; + } else { + /* limit tx_tick_nb anyway to avoid large tx bursts */ + tx_tick_nb = min(tx_tick_nb, 5); + } +#if 0 + { + struct timeval t; + mcl_gettimeofday(&t); + printf("time = (%d,%d)\n", (int)t.tv_sec, (int)t.tv_usec); + } + printf("eltc=%d, elit=%d, true_tx_tick_nb=%f, rate=%f pkt/tick, elit(sec)=%f, remaining_tx_tick_nb=%f, tx_tick_nb=%d\n", + eltc, elit, true_tx_tick_nb, mclcb->tx.get_pkt_per_tick_tx_rate(), mcl_it2sec(elit), + this->remaining_tx_tick_nb, tx_tick_nb); +#endif // 0 + /* call the tx function for each tx_tick */ + for (int i = tx_tick_nb; i > 0; i--) { + mclcb->tx.try_to_send(mclcb); + } + } + +#if 0 + /* + * launch memory cleanup function periodically + */ + if (mclcb->sender && mclcb->delivery_mode == DEL_MODE_STREAMING +#ifdef VIRTUAL_TX_MEM + && !(mclcb->vtm_used) +#endif /* VIRTUAL_TX_MEM */ + && eltc > 0) { + /* update counter */ + mclcb->tx_mem_cleanup_count -= eltc; + if (mclcb->tx_mem_cleanup_count < 0) { + mclcb->tx_mem_cleanup_count = + TX_MEM_CLEANUP_PERIOD / MCL_PERIODIC_TIMER_PERIOD; + mcl_tx_cleanup(mclcb); + } + } + // + // mclcb->tx_mem_cleanup_rem_it = mcl_itime_sub(mclcb->tx_mem_cleanup_rem_it, elit); + // if (mcl_itime_leq_0(mclcb->tx_mem_cleanup_rem_it)) { + // if (mclcb->first_tx_for_mclcb == 0) { + // /* clean only after tx start */ + // mcl_tx_cleanup(mclcb); + // } + // mclcb->tx_mem_cleanup_rem_it = mcl_usec2it(TX_MEM_CLEANUP_PERIOD); + // } + + /* + * print stats periodically + */ + if (mclcb->statistics == 2) { + mclcb->stats_time_count -= eltc; + if (mclcb->stats_time_count < 0) { + mclcb->stats_time_count = STATS_PERIOD / MCL_PERIODIC_TIMER_PERIOD; + if (mclcb->sender) + mcl_print_tx_stats(mclcb); + if (mclcb->receiver) + mcl_print_rx_stats(mclcb); + /* nb: stats_period is init'ed in func*/ + } + //mclcb->stat_rem_it = mcl_itime_sub(mclcb->stat_rem_it, elit); + //if (mcl_itime_leq_0(mclcb->stat_rem_it)) { + // mclcb->stat_rem_it = mcl_user2it(); + // if (mclcb->sender) + // mcl_print_tx_stats(mclcb); + // if (mclcb->receiver) + // mcl_print_rx_stats(mclcb); + // /* nb: stats_period is init'ed in func*/ + //} + } + +#endif // 0 + TRACELVL(5, (mcl_stdout, "<- mcl_periodic_proc::mcl_do_periodic_proc:\n")) +} + diff --git a/src/norm/mcl_periodic_proc.h b/src/norm/mcl_periodic_proc.h new file mode 100644 index 0000000..ffd147f --- /dev/null +++ b/src/norm/mcl_periodic_proc.h @@ -0,0 +1,93 @@ +/* $Id: mcl_periodic_proc.h,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_PERIODIC_PROC_H +#define MCL_PERIODIC_PROC_H + + +/** + * This class gathers additional variables and member functions that are + * specific to each MCL session. This class is included by mcl_cb class. + */ +class mcl_periodic_proc { + +public: + /****** Public Members ************************************************/ + + /** + * Default constructor. + */ + mcl_periodic_proc (); + + /** + * Default destructor. + */ + ~mcl_periodic_proc (); + + /** + * Scan all the MCL sessions. + * Called periodically, unlocked, by the mcl_periodic_timer thread. + * There is only one instance of this function since it is + * independant of the MCL session. + */ + static void scan_all_sessions (void); + + /** + * Calls the various functions that perform periodic processing for + * a given session. + * Called by scan_all_sessions() for each valid mcl_cb, and also + * called (locked), by mcl_send(to)() to anticipate data + * transmissions while doing FEC encoding. + * @param mclcb session considered + */ + void do_periodic_proc (mcl_cb *mclcb); + + + /****** Public Attributes *********************************************/ + + /** Time_count of last do_periodic_proc call. */ + int last_periodic_proc_tc; + /** itimer of last do_periodic_proc call. */ + mcl_itime_t last_periodic_proc_it; + /** Fractional tick_nb in do_periodic_proc. */ + float remaining_tx_tick_nb; + +#if 0 + /** tx memory cleanup function call counter. */ + int tx_mem_cleanup_count; + /** periodic stats print counter. */ + int stats_time_count; +#endif // 0 + +private: + /****** Private Members ***********************************************/ + + /****** Private Attributes ********************************************/ + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +#endif // !MCL_PERIODIC_PROC_H diff --git a/src/norm/mcl_profile.h b/src/norm/mcl_profile.h new file mode 100644 index 0000000..850cce9 --- /dev/null +++ b/src/norm/mcl_profile.h @@ -0,0 +1,264 @@ +/* $Id: mcl_profile.h,v 1.8 2004/05/26 12:54:56 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * This file contains various parameters that can be modified to suit + * specific needs. Modify with care in any case... + * It is composed of two parts: + * + * - PART 1: those are the NORM specific parameters. + * + * - PART 2: those are the MCL specific parameters. They concern the + * library itself, and modifying them can help MCL suit a + * specific application (e.g. increase MCL_MAX_ID if the + * application opens many simultaneous sessions). + * This is also the place where packet loss rates can be + * specified for simulations... + */ + +#ifndef MCL_PROFILE_H +#define MCL_PROFILE_H + + +/****** NORM profile options **************************************************/ + + +/* + * Do you want IPv6 support? + */ +#define INET6 + + +/** + * Some control packets are sent MCL_TX_ROBUSTNESS_FACTOR times + * for improved robustness. + */ +const UINT32 MCL_TX_ROBUSTNESS_FACTOR = 10; +/** 2 should be enough for FLUSH transmissions since they are cumulative. */ +const UINT32 MCL_TX_CMD_FLUSH_ROBUSTNESS_FACTOR = 2; + + +/* + * Various NORM timers and parameters of the sender (see mcl_tx_ctrl.[h|cpp]) + */ + +/** + * Waiting time after a FLUSH transmission. + * At timeout, a new FLUSH can be sent again or the block free'ed. + * Timer duration in msec. + */ +const INT32 FLUSH_DONE_TIMEOUT = 1000; + +/** + * Determines how many FLUSH messages must be sent before considering + * that the block has been reliably delivered. + * This process is interrupted in case a NACK for this block is received. + */ +const INT32 UNANSWERED_FLUSH_REPEAT_COUNT = 2; // send twice a FLUSH if + // there is no answer... + +/** + * Waiting time after a NACK processing (and repair packets have been sent) + * before issuing a new FLUSH. + * Timer duration in msec. + */ +const INT32 RETX_DONE_TIMEOUT = 1000; + + +/* + * Various NORM timers and parameters of a receiver (see mcl_rx_ctrl.[h|cpp]) + */ + +/* ... */ + + +/****** MCL lib profile options ***********************************************/ + + +/** + * Max number of sessions per instance of the MCL library. + * Large numbers are possible if you have enough memory, disk space and CPU + * power ;-) + * Note that some systems (e.g. solaris) are more strict on the default + * maximum number of sockets in use. + * Note also that setting MCLCB_MAX_ID to a certain value does not mean + * that you can open up to this value, because of the way IDs are allocated + * (see mcl_cb::mcl_cb). To get a unique ID in the file descriptor space, + * we duplicate stdin and use the returned value. Therefore, since file + * descriptors 0, 1, and 2 are already allocated, MCLCB_MAX_ID should be + * at least equal to 3, or more if the upper application has opened one + * or more files. + */ +const INT32 MAX_NB_MCLCB = 20; + + +/** + * Do you want to use the Reed-Solomon FEC codec? + */ +#define RSE_FEC + +#if defined(RSE_FEC) || defined(LDPC_FEC) +#define FEC +#endif + + +#ifdef RSE_FEC +/** + * Do you want proactive FEC (ie. FEC packets sent along with data packets + * to immediately recover possible erasures) or not? + */ +#define MCL_USE_PROACTIVE_FEC +#ifdef MCL_USE_PROACTIVE_FEC +/** + * Defines the number of default proactive FEC packets created per block. + * The number of FEC symbols created is equal to ratio * du_nb + */ +const float MCL_PROACTIVE_FEC_RATIO = 0.10; +//const float MCL_PROACTIVE_FEC_RATIO = 0.25; +#endif +#endif // RSE_FEC + + +#ifdef FEC +/* + * parameters associated to the use of FEC: + * - maximum value of k for (k,n) FEC codecs; this is also the number + * of source symbols (i.e. of DUs) per block + * - maximum value of n for (k, n) FEC codecs; n-k is also the maximum number + * of FEC symbols that can be generated per block + * - FEC redundancy, or n/k ratio; e.g. 1.5 for 50% of FEC, 2.0 for 100% + * which is a by product of setting the k and n parameters + */ +//const double MAX_FEC_RATIO = 4.0; /* max ratio of fec pkts generated */ +//const double DEFAULT_FEC_RATIO = 1.5;/* dflt ratio of fec pkts generated */ + +#ifdef RSE_FEC +#define RSE_MAX_K GF_SIZE /* at most max_k DUs per source block */ +#define RSE_MAX_N GF_SIZE /* at most max_n DUs after encoding */ +const INT32 RSE_DEFAULT_K = 64; /* default */ +const INT32 RSE_DEFAULT_N = 128; /* default */ +#endif +#ifdef LDPC_FEC +const INT32 LDPC_MAX_K = 200*1000; /* at most 200*10^3 packets per block */ +const INT32 LDPC_MAX_N = 200*1000; /* at most 200*10^3 packets after enc */ +const INT32 LDPC_DEFAULT_K = 20*1000; /* default: 20*10^3 packets */ +const INT32 LDPC_DEFAULT_N = 40*1000; /* default: 40*10^3 packets */ +#endif +#endif /* FEC */ + + +/** + * The size of the timer array. This is the limit on the number of + * simultaneous timers that may be active at any time. + * Used by the RMF (mcl_timer.h/ccp) code. + */ +const INT32 MCL_TIMER_ARRAY_SIZE = 512; + + +/** + * default polling period. + * This is a compromize, not too high to limit resource consumption, + * not too low to have a good reactivity. + */ +//const INT32 DFLT_POLLING_PERIOD = ((UINT32)5 * MCL_PERIODIC_TIMER_PERIOD); +#define DFLT_POLLING_PERIOD ((UINT32)5 * MCL_PERIODIC_TIMER_PERIOD) + + +/** + * Max and default size of sockets. + * Must be large enough to absort packet bursts. + */ +const INT32 MCL_MAX_SOCKET_SIZE = (64*1024); +const INT32 MCL_DFLT_SOCKET_SIZE = MCL_MAX_SOCKET_SIZE; + + +/* + * mtu max tx unit as defined by the physical layer (it does not + * consider IP and above headers) + * payload data payload of a NORM packet (if any) + * header NORM header only + * datagram includes payload plus NORM header. This is the unit given to UDP + * ip_datagram includes datagram plus UDP/IP headers + * + * WARNING: changes of these sizes must be done both at source and receivers... + */ +//const INT32 DFLT_MTU = 576; +const INT32 DFLT_MTU = 1500; + +const INT32 UDP_IPv4_HEADER_SIZE = (8 + 20); // in case of IPv4 + +// NORM headers cannot be smaller in any case +const INT32 MIN_NORM_HDR_SIZE = 64; +// NORM headers cannot be larger in case of a DATA NORM packet +const INT32 MAX_NORM_HDR_SIZE_FOR_DATA = 64; + +const INT32 MAX_DATAGRAM_SIZE = (DFLT_MTU - UDP_IPv4_HEADER_SIZE); +const INT32 DFLT_DATAGRAM_SIZE = MAX_DATAGRAM_SIZE; + +const INT32 MAX_PAYLOAD_SIZE = (MAX_DATAGRAM_SIZE - + MAX_NORM_HDR_SIZE_FOR_DATA); +const INT32 DFLT_PAYLOAD_SIZE = MAX_PAYLOAD_SIZE; + + + +/** + * Create temporary file in this dir (e.g. used by the storage service). + */ +#define MCL_DEFAULT_TMP_DIR_NAME "/tmp/" + + +/** + * Do you want that all traces (out and error) are sent to a dedicated + * file in the temporary directory defined above or to the stdout and + * stderr standard output? + */ +//#define STDOUT_TO_FILE + + +/* + * Do you want to simulate random bursty packet losses? + * (i.e. the source will randomly forget to send some bursts of packets) + * Usually NO... + */ +//#define SIMUL_TX_LOSSES +//#define SIMUL_RX_LOSSES // not yet supported + +#if defined(SIMUL_TX_LOSSES) || defined(SIMUL_RX_LOSSES) +/* + * Should losses be independant of layer number (ie be constant) or not ? + */ +#define CONSTANT_LOSS_RATIO +/* + * number of (simulated) losses in % when the previous packet was OK + */ +#define P_LOSS_WHEN_OK 1 +//#define P_LOSS_WHEN_OK 5 +//#define P_LOSS_WHEN_OK 20 +/* + * number of (simulated) losses in % when the previous packet was LOST + */ +#define P_LOSS_WHEN_LOSSES 10 +//#define P_LOSS_WHEN_LOSSES 50 +#endif /* SIMUL_XX_LOSSES */ + + +#endif // MCL_PROFILE_H + diff --git a/src/norm/mcl_rx.cpp b/src/norm/mcl_rx.cpp new file mode 100644 index 0000000..26dd175 --- /dev/null +++ b/src/norm/mcl_rx.cpp @@ -0,0 +1,605 @@ +/* $Id: mcl_rx.cpp,v 1.5 2004/05/26 07:36:04 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +mcl_rx::mcl_rx () +{ +} + + +mcl_rx::~mcl_rx () +{ +} + + +/** + * Process the incoming packet just received. + * This can be a pure signaling packet or a pure data packet, or + * a data packet plus a signaling header (usual case). + * This function and the following ones take control of the pbuf + * buffer, and can free it when required... + * This function is used both by a sender (for feedback packets) + * and a receiver (data and control packets). + */ +void +mcl_rx::process_pkt (mcl_cb *const mclcb, + mcl_rx_pkt *pkt, + mcl_addr *saddr) +{ + mcl_common_hdr_infos_t chdr_infos; // infos of common hdr, host format + + TRACELVL(5, (mcl_stdout, "-> mcl_rx::process_pkt:\n")) + ASSERT(pkt && pkt->pkt_len > 0); + ASSERT(saddr && saddr->get_port() > 0); + TRACELVL(4, (mcl_stdout, + "mcl_rx::process_pkt: ses_id=%d, from %s/%d, len=%d\n", + mclcb->get_id(), + saddr->get_addr_string(), saddr->get_port(), + pkt->pkt_len)) + if (mclcb->fsm.is_closed(mclcb)) { + /* + * the session has been closed in the meanwhile... ignore + */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx::process_pkt: ignored (session closed)\n")) + delete pkt; + return; + } + if (mclcb->get_verbosity() >= 4) { + /* dump at most 16 32-bit words */ + mcl_dump_buffer(pkt->get_buf(), pkt->pkt_len, 16); + } + /* + * process the NORM common header first and perform some + * verifications at the same time + */ + memset(&chdr_infos, 0, sizeof(mcl_common_hdr_infos_t)); + if (mclcb->norm_pkt_mgmt.parse_common_hdr(mclcb, pkt, &chdr_infos) + == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_rx::process_pkt: ERROR, bad NORM header\n")) + goto bad_hdr; + } + /* + * perform type-specific processing now + */ + switch (chdr_infos.type) { + case NORM_DATA: + /* receiver specific */ + TRACELVL(5, (mcl_stdout, + " mcl_rx::process_pkt: NORM_DATA\n")) + if (this->process_data_pkt(mclcb, pkt, saddr, &chdr_infos) + == MCL_ERROR) { + goto bad; + } + break; + + case NORM_CMD: + TRACELVL(5, (mcl_stdout, + " mcl_rx::process_pkt: NORM_CMD\n")) + if (mclcb->rx_ctrl.process_cmd_pkt(mclcb, pkt, saddr, &chdr_infos) + == MCL_ERROR) { + goto bad; + } + break; + + case NORM_NACK: + /* sender specific */ + TRACELVL(5, (mcl_stdout, + " mcl_rx::process_pkt: NORM_NACK\n")) + if (mclcb->tx_ctrl.process_nack_pkt(mclcb, pkt, saddr, &chdr_infos) + == MCL_ERROR) { + goto bad; + } + break; + + + default: + PRINT_ERR((mcl_stderr, + "mcl_rx::process_pkt: ERROR, unknown NORM header %d\n", + chdr_infos.type)) + goto bad_hdr; + } + + + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_pkt:\n")) + return; + +bad_hdr: + mclcb->stats.bad_hdr++; + mclcb->stats.errors++; + delete pkt; + +bad: + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_pkt: ERROR\n")) + return; +} + + +/** + * Process an incoming NORM_DATA packet. + * @param mclcb + * @param pkt pointer to packet + * @param saddr source address for this packet + * @param chdr_infos pointer to the common_infos struct + */ +mcl_error_status +mcl_rx::process_data_pkt(mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_addr *saddr, + mcl_common_hdr_infos_t *chdr_infos) +{ + mcl_data_hdr_infos_t dhdr_infos; // infos of data hdr, host format + INT32 hlen; // total header length + INT32 len; // payload length (without headers) + mcl_du *du; // DU for this data packet + mcl_block *blk; // block for this data packet + mcl_adu *adu; // ADU for this data packet + + TRACELVL(5, (mcl_stdout, "-> mcl_rx::process_data_pkt:\n")) + /* + * process the NORM DATA header + */ + memset(&dhdr_infos, 0, sizeof(mcl_data_hdr_infos_t)); + if (mclcb->norm_pkt_mgmt.parse_data_hdr(mclcb, pkt, &dhdr_infos) + == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_rx::process_data_pkt: ERROR, bad NORM header\n")) + goto bad_hdr_no_du_free; + } + hlen = sizeof(norm_common_hdr_t) + sizeof(norm_data_hdr_t); + len = pkt->pkt_len - hlen; + /* + * check what we got... + */ + ASSERT(len >= 0); + if (len == 0) { + /* empty data packet... nothing else to do */ + PRINT_ERR((mcl_stderr, + "mcl_recv_it: ERROR, empty data packet\n")) + goto bad_hdr_no_du_free; + } + /* + * check that packet actually contains the announced payload + */ + if (len != (INT32)dhdr_infos.du_len) { + /* no payload whereas some has been announced */ + PRINT_ERR((mcl_stderr, + "mcl_rx::parse_data_hdr: ERROR, too short, no room for payload (%d announced, got %d)\n", + dhdr_infos.du_len, len)) + goto bad_hdr_no_du_free; + } + if (mclcb->get_verbosity() >= 1) + mcl_print_recvd_du(mclcb, true, 0, &dhdr_infos); + /* + * create its descriptor + */ + du = new mcl_du; + du->block = NULL; + du->seq = dhdr_infos.idf_du; + du->len = len; + du->data = pkt->get_buf() + hlen; + du->pkt = pkt; + du->is_fec = dhdr_infos.is_fec; + du->set_next(NULL); + du->set_prev(NULL); + /* + * update stats now (includes duplicated packets) + */ + if (du->is_fec) { + mclcb->stats.rx_fec_pkts++; + mclcb->stats.rx_fec_bytes += hlen + len; + } else { + mclcb->stats.rx_data_pkts++; + mclcb->stats.rx_data_bytes += hlen + len; + } + mclcb->stats.rx_tot_pkts++; + mclcb->stats.rx_tot_bytes += hlen + len; + /* + * find the right ADU first... + */ + if (!(adu = mclcb->rx_window.find_adu(mclcb, dhdr_infos.idf_adu))) { + /* + * this is the first packet of a new ADU, so register the adu + * first... + */ + if (mclcb->rx_window.process_adu_announcement(mclcb, saddr, &dhdr_infos) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_rx::parse_data_hdr: adu announcement registering failed\n")) + delete du; + goto bad; + } + if (!(adu = mclcb->rx_window.find_adu(mclcb, dhdr_infos.idf_adu))) { + /* + * orphan du (we received a DU before the announcement + * of its ADU). + */ + PRINT_ERR((mcl_stderr, + "mcl_rx::parse_data_hdr: ERROR1, orphan DU [%d/%d/%d] (no adu)\n", + dhdr_infos.idf_adu, dhdr_infos.idf_block, du->seq)) + delete du; + goto bad; + } + } + if (adu->get_rx_status() == ADU_STATUS_DECODED || + adu->get_rx_status() == ADU_STATUS_DELIVERED) { + /* useless du as the ADU is already decoded and/or delivered */ + TRACELVL(5, (mcl_stdout, + " mcl_rx::process_data_pkt: useless, ADU already decoded or completed\n")) + goto duplicated; + } + /* + * ... and then the right block... + */ + if (!(blk = adu->find_block(mclcb, dhdr_infos.idf_block))) { + /* + * orphan du (we received a DU before the announcement + * of its ADU). Should put it in mclcb->rxlvl.du_head... TO DO. + */ + PRINT_ERR((mcl_stderr, + "mcl_recv_it: ERROR2, orphan DU [%d/%d/%d] (no block)\n", + dhdr_infos.idf_adu, dhdr_infos.idf_block, du->seq)) + delete du; + goto bad; + } + if (blk->get_rx_status() == BLK_STATUS_DECODED) { + /* useless du as the block is already decoded */ + TRACELVL(5, (mcl_stdout, + " mcl_rx::process_data_pkt: useless, block already decoded\n")) + goto duplicated; + } + if (blk->get_rx_status() == BLK_STATUS_COMPLETED) { + if (du->is_fec) { + /* can't do anything interesting with it */ + /* useless du as block already completed */ + TRACELVL(5, (mcl_stdout, + " mcl_rx::process_data_pkt: useless FEC du, block already completed\n")) + goto duplicated; + } else { + /* it is possible that this data DU can replace a + * FEC du. Depends if DU has already been received + * or not! + * If possible, do it as FEC decoding is simplified. + */ + } + } + du->block = blk; + ASSERT(du->block->adu == adu); + + /* + * ... check if it is a duplicated du or not + */ + if (du->is_fec) { + if (blk->insert_in_fec_du_list(mclcb, du) == MCL_ERROR) { + /* duplicated FEC du */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx::process_data_pkt: duplicated FEC du\n")) + goto duplicated; + } + //blk->fec_du_nb++; + } else { + /* this is a data DU */ + if (blk->insert_in_du_list(mclcb, du) == MCL_ERROR) { + /* duplicated du */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx::process_data_pkt: duplicated data du\n")) + goto duplicated; + } + if (blk->get_rx_status() == BLK_STATUS_COMPLETED) { + /* this data DU can indeed replace a FEC du */ +#if 0 //#ifdef VIRTUAL_RX_MEM + if (mcl_vrm_can_store_in_vrm(mclcb, du->len)) { + /* use the VRMEM service to register data */ + if (mcl_vrm_store_data(mclcb, du, du->data, du->len)) { + PRINT_ERR((mcl_stderr, "mcl_recv_it: ERROR: Virtual Rx Memory service failed\n")) + goto bad; + } + /* pbuf no longer required... free it! */ + free(pbuf); + pbuf = NULL; + } else if (mclcb->vrm_used) { + /* remember it kept in physical memory */ + mcl_vrm_register_in_prm(mclcb, du, du->len); + } +#endif /* VIRTUAL_RX_MEM */ + /* TODO: free a fec du immediately! */ + goto duplicated_nofree; /* to update dupl stats */ + } + } + /* + * ... no, so store it + */ +#if 0 //#ifdef VIRTUAL_RX_MEM + if (mcl_vrm_can_store_in_vrm(mclcb, du->len)) { + /* + * use the VRMEM service to register data + */ + if (mcl_vrm_store_data(mclcb, du, du->data, du->len)) { + PRINT_ERR((mcl_stderr, "mcl_recv_it: ERROR: Virtual Rx Memory service failed\n")) + goto bad; + } + /* pbuf no longer required... free it! */ + free(pbuf); + pbuf = NULL; + } else if (mclcb->vrm_used) { + /* remember it kept in physical memory */ + mcl_vrm_register_in_prm(mclcb, du, du->len); + } +#endif /* VIRTUAL_RX_MEM */ + /* + * update stats now (non-duplicated packets only) + */ + mclcb->stats.rx_undup_pkts++; + mclcb->stats.buf_space += len; + if (mclcb->stats.buf_space > mclcb->stats.max_buf_space) + mclcb->stats.max_buf_space = mclcb->stats.buf_space; + /* + * was du the last DU of a block? + */ + if (blk->check_if_completed_and_process(mclcb)) { + /* + * was du the last DU of an ADU ? + */ + adu->check_if_completed_and_process(mclcb); + } + + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_data_pkt:\n")) + return MCL_OK; + + +duplicated: + mclcb->stats.rx_dupl_pkts++; + mclcb->stats.rx_dupl_bytes += du->len; + delete du; // free the pkt too + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_data_pkt: duplicated_1\n")) + return MCL_OK; + +duplicated_nofree: + mclcb->stats.rx_dupl_pkts++; + mclcb->stats.rx_dupl_bytes += du->len; + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_data_pkt: duplicated_2\n")) + return MCL_OK; + + +bad_hdr_no_du_free: + mclcb->stats.bad_hdr++; + mclcb->stats.errors++; + delete pkt; // no du object yet, so free pkt explicitely + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_data_pkt: ERROR, bad hdr\n")) + return MCL_ERROR; + +bad: + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_data_pkt: ERROR\n")) + return MCL_ERROR; +} + + +#if 0 +/** + * Process an incoming NORM_CMD packet. + * @param mclcb + * @param pkt pointer to packet + * @param saddr source address for this packet + * @param chdr_infos pointer to the common_infos struct + */ +mcl_error_status +mcl_rx::process_cmd_pkt(mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_addr *saddr, + mcl_common_hdr_infos_t *chdr_infos) +{ + mcl_data_hdr_infos_t dhdr_infos; // infos of data hdr, host format + //INT32 hlen; // total header length + //INT32 len; // payload length (without headers) + + TRACELVL(5, (mcl_stdout, "-> mcl_rx::process_cmd_pkt:\n")) + /* + * process the NORM DATA header + */ + memset(&dhdr_infos, 0, sizeof(mcl_data_hdr_infos_t)); + if (mclcb->norm_pkt_mgmt.parse_cmd_hdr(mclcb, pkt, &dhdr_infos) + == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_rx::process_cmd_pkt: ERROR, bad NORM header\n")) + goto bad_hdr; + } + + switch (dhdr_infos.cmd_flavor) { + case NORM_CMD_FLUSH: + TRACELVL(5, (mcl_stdout, " mcl_rx::process_cmd_pk: FLUSH\n")) + // TODO + break; + + case NORM_CMD_NO_NEW_OBJECT: + TRACELVL(5, (mcl_stdout, " mcl_rx::process_cmd_pk: NO_NEW_OBJECT\n")) + if (mclcb->fsm.no_new_adu(mclcb)) { + /* this is a duplicated announce; ignore */ + break; + } + if (mclcb->get_verbosity() >= 2) + mcl_print_recvd_du(mclcb, false, MCL_SIG_NONEWADU, &dhdr_infos); + mclcb->rx.set_highest_adu_seq_of_session(dhdr_infos.max_idf_adu); + mclcb->fsm.update_rx_state(mclcb, REVENT_NO_NEW_ADU); + + break; + + case NORM_CMD_CLOSE: + TRACELVL(5, (mcl_stdout, " mcl_rx::process_cmd_pk: CLOSE\n")) + if (mclcb->fsm.close_already_rx(mclcb)) { + /* this is a duplicated announce; ignore */ + break; + } + if (mclcb->get_verbosity() >= 2) + mcl_print_recvd_du(mclcb, false, MCL_SIG_CLOSE, &dhdr_infos); + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_RECV); + ASSERT(mclcb->fsm.no_new_adu(mclcb)); + if (mclcb->get_stats_level() >= 1) { + mclcb->stats.print_rx_stats(mclcb); + mclcb->stats.print_final_stats(mclcb); + } + break; + + default: + exit(-1); + } + + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_cmd_pkt:\n")) + return MCL_OK; + + +bad_hdr: + mclcb->stats.bad_hdr++; + mclcb->stats.errors++; + delete pkt; // no du object yet, so free pkt explicitely + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_data_pkt: ERROR, bad hdr\n")) + return MCL_ERROR; + +#ifdef NOT_YET +bad: + TRACELVL(5, (mcl_stdout, "<- mcl_rx::process_data_pkt: ERROR\n")) + return MCL_ERROR; +#endif +} +#endif // 0 + + +/** + * Try to return an ADU to the appli. + * Maybe there is a gap and this is not possible... + * Return the amount of data copied to userbuf, 0 if some + * data is available but not copied to userbuf, and < 0 if + * no data is available. + */ +INT32 +mcl_rx::return_adu_to_appli(mcl_cb *const mclcb, + char * userbuf, + INT32 userlen, + struct sockaddr * saddr, + INT32 * saddr_len) +{ + mcl_adu *adu; + mcl_block *blk; + mcl_du *du; + mcl_du *ndu; /* next du */ + char *dst; /* where to do data copy in userbuf */ + INT32 i, j; + INT32 len, rem; /* remaining data for copy to userbuf */ + + + TRACELVL(5, (mcl_stdout, + "-> mcl_rx::return_adu_to_appli: userbuf=x%x, len=%d\n", + (INT32)userbuf, userlen)) + /* + * find a ready adu first, depending on the receiving delivery mode... + */ + adu = mclcb->rx_window.get_next_ready_adu(mclcb); + if (adu == NULL) { + TRACELVL(5, (mcl_stdout, "<- mcl_rx::return_adu_to_appli: no adu ready\n")) + return -1; + } + if (userlen <= 0) { + /* it was just to check if an ADU was available... */ + ASSERT(userbuf); + return 0; + } + ASSERT(userbuf && userlen > 0); +#if 0 + /* + * ok, so remove the adu from rx list + */ + mclcb->rx_window.remove_adu(mclcb, adu); +#endif + /* + * then copy data... + * it requires to go through all the DUs of all the blocks of the ADU + */ + rem = userlen; + dst = userbuf; + for (i = adu->get_block_nb(), blk = adu->get_block_head(); + i > 0; i--, blk++) { + ASSERT(blk->du_nb <= blk->get_du_nb_in_list()); + ASSERT(blk->get_fec_du_nb_in_list() == 0); + for (j = blk->du_nb, du = blk->get_du_head(); j > 0 && rem > 0; + j--, du = ndu) { + /* don't copy more than remaining space in buf */ + if (rem < du->len) { + len = rem; + PRINT_ERR((mcl_stderr, + "mcl_rx::return_adu_to_appli: ERROR: user buffer too short (%d required, %d available). Truncated\n", + adu->get_len(), userlen)) + mclcb->stats.other_errors++; + } else { + len = du->len; + } + /* copy data in appli's buffer */ + memcpy(dst, du->data, len); + dst += len; + rem -= len; + ndu = du->get_next(); + //mclcb->stats.buf_space -= du->len; + } + } + /* + * adu is about to be delivered... + */ + mclcb->rx_window.mark_adu_delivered(adu); + /* + * free all buffers (blocks, data DUs, FEC DUs) now... + */ + adu->remove_and_free_all_buffers(mclcb); + /* + * copy source addr in appli's buffer + */ + if (saddr) { + if (saddr_len == NULL || + *saddr_len < (INT32)sizeof(struct sockaddr_in)) { + PRINT_ERR((mcl_stderr, + "mcl_rx::return_adu_to_appli: ERROR, addr buffer too short (%d expected, got %d)\n", + sizeof(struct sockaddr_in), *saddr_len)) + mcl_exit(-1); + } + adu->addr.get_addr_struct((struct sockaddr_in*)saddr); + *saddr_len = sizeof(struct sockaddr_in); + } + //ASSERT(mclcb->ready_data >= 0); +#ifdef DEBUG + if (mclcb->get_verbosity() >= 4) { + /* just to check data received... will be in appli */ + mcl_dump_buffer(userbuf, adu->get_len(), adu->get_len() >> 2); + } +#endif + if (mclcb->get_verbosity() == 2) { + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tadu_delivered seq=%d len=%d\n", + time.tv_sec, time.tv_usec, adu->get_seq(), adu->get_len())) +#ifdef GET_SYSINFO + mcl_print_sysinfo(mclcb); +#endif + } + /* + * update stats + */ + TRACELVL(5, (mcl_stdout, "<- GiveADUtoAppli: %d bytes returned\n", userlen - rem)) + return (userlen - rem); +} + diff --git a/src/norm/mcl_rx.h b/src/norm/mcl_rx.h new file mode 100644 index 0000000..4798427 --- /dev/null +++ b/src/norm/mcl_rx.h @@ -0,0 +1,128 @@ +/* $Id: mcl_rx.h,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_RX_H +#define MCL_RX_H + +/** + * Reception class. + */ +class mcl_rx { + +public: + /****** Public Members ************************************************/ + mcl_rx (); + ~mcl_rx (); + + /** + * Set the highest adu seq number of this session as announced + * with NO_NEW_OBJECT. + * @return highest adu seq number or 0 if unknown. + */ + void set_highest_adu_seq_of_session (UINT32 max_id); + + /** + * Return the highest adu seq number of this session if any. + * @return highest adu seq number or 0 if unknown. + */ + UINT32 get_highest_adu_seq_of_session () const; + + /** + * Process the incoming packet just received. + * This can be a pure signaling packet or a pure data packet, or + * a data packet plus a signaling header (usual case). + * This function and the following ones take control of the pbuf + * buffer, and can free it when required... + * This function is used both by a sender (for feedback packets) + * and a receiver (data and control packets). + */ + void process_pkt (mcl_cb *const mclcb, class mcl_rx_pkt *pkt, + mcl_addr *saddr); + + /** + * Try to return an ADU to the appli. + * Maybe there is a gap and this is not possible... + * Return the amount of data copied to userbuf, 0 if some + * data is available but not copied to userbuf, and < 0 if + * no data is available. + */ + INT32 return_adu_to_appli(mcl_cb *const mclcb, + char *userbuf, INT32 userlen, + struct sockaddr *saddr, INT32 *saddr_len); + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + + /** + * Process an incoming NORM_DATA packet. + * @param mclcb + * @param pkt pointer to packet + * @param saddr source address for this packet + * @param chdr_infos pointer to the common_infos struct + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status process_data_pkt (mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_addr *saddr, + mcl_common_hdr_infos_t *chdr_infos); + +#if 0 + /** + * Process an incoming NORM_CMD packet. + * @param mclcb + * @param pkt pointer to packet + * @param saddr source address for this packet + * @param chdr_infos pointer to the common_infos struct + */ + mcl_error_status process_cmd_pkt(mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_addr *saddr, + mcl_common_hdr_infos_t *chdr_infos); +#endif + + + /****** Private Attributes ********************************************/ + + UINT32 max_adu_seq; // highest ADU seq nb + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline void +mcl_rx::set_highest_adu_seq_of_session (UINT32 max_id) +{ + this->max_adu_seq = max_id; +} + +inline UINT32 +mcl_rx::get_highest_adu_seq_of_session () const +{ + return this->max_adu_seq; +} + +#endif // MCL_RX_H diff --git a/src/norm/mcl_rx_ctrl.cpp b/src/norm/mcl_rx_ctrl.cpp new file mode 100644 index 0000000..398413a --- /dev/null +++ b/src/norm/mcl_rx_ctrl.cpp @@ -0,0 +1,487 @@ +/* $Id: mcl_rx_ctrl.cpp,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + +/** + * Default constructor. + */ +mcl_rx_ctrl::mcl_rx_ctrl() +{ + this->NACK_tevent_head = NULL; +} + + +/** + * Process an incoming NORM_CMD packet. + * @param mclcb + * @param pkt pointer to packet + * @param saddr source address for this packet + * @param chdr_infos pointer to the common_infos struct + */ +mcl_error_status +mcl_rx_ctrl::process_cmd_pkt (mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_addr *saddr, + mcl_common_hdr_infos_t *chdr_infos) +{ + mcl_data_hdr_infos_t dhdr_infos; // infos of data hdr, host format + //INT32 hlen; // total header length + //INT32 len; // payload length (without headers) + + TRACELVL(5, (mcl_stdout, "-> mcl_rx_ctrl::process_cmd_pkt:\n")) + /* + * process the NORM DATA header + */ + memset(&dhdr_infos, 0, sizeof(mcl_data_hdr_infos_t)); + if (mclcb->norm_pkt_mgmt.parse_cmd_hdr(mclcb, pkt, &dhdr_infos) + == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_rx_ctrl::process_cmd_pkt: ERROR, bad NORM header\n")) + goto bad_hdr; + } + + switch (dhdr_infos.cmd_flavor) { + + case NORM_CMD_FLUSH: { + mcl_rx_ctrl_NACK_tevent *tevent; + const INT32 START_NACK_PROCESS_MAX_TIMEOUT = 10; + // timer duration in msec + tevent = new mcl_rx_ctrl_NACK_tevent(dhdr_infos.idf_adu, + dhdr_infos.idf_block, + saddr); + /* + * remove FLUSH duplicates that can exist because of the + * ROBUST factor! + */ + if (tevent->find_in_list(mclcb, &(this->NACK_tevent_head))) { + /* FLUSH already received, because of the ROBUST + * factor */ + TRACELVL(5, (mcl_stdout, + " mcl_rx_ctrl::process_cmd_pkt: FLUSH ignored (already rx)\n")) + delete tevent; + } else { + /* new FLUSH + * insert it in the tevent list and set a timer for + * delayed FLUSH processing */ + PRINT_LVL(1, (mcl_stdout, + "\tFLUSH recvd for blk %d/%d\n", + dhdr_infos.idf_adu, dhdr_infos.idf_block)) + tevent->insert_in_list(mclcb, &(this->NACK_tevent_head)); + mclcb->timer.set_timer(START_NACK_PROCESS_MAX_TIMEOUT, + (mcl_timer_handler *)this, + (INT32)mclcb, (INT32)tevent); + } + break; + } + + case NORM_CMD_NO_NEW_OBJECT: + TRACELVL(5, (mcl_stdout, + " mcl_rx_ctrl::process_cmd_pkt: NO_NEW_OBJECT\n")) + if (mclcb->fsm.no_new_adu(mclcb)) { + /* this is a duplicated announce; ignore */ + break; + } + if (mclcb->get_verbosity() >= 2) + mcl_print_recvd_du(mclcb, false, MCL_SIG_NONEWADU, + &dhdr_infos); + mclcb->rx.set_highest_adu_seq_of_session(dhdr_infos.max_idf_adu); + mclcb->fsm.update_rx_state(mclcb, REVENT_NO_NEW_ADU); + + break; + + case NORM_CMD_CLOSE: + TRACELVL(5, (mcl_stdout, + " mcl_rx_ctrl::process_cmd_pkt: CLOSE\n")) + if (mclcb->fsm.close_already_rx(mclcb)) { + /* this is a duplicated announce; ignore */ + break; + } + if (mclcb->get_verbosity() >= 2) + mcl_print_recvd_du(mclcb, false, MCL_SIG_CLOSE, + &dhdr_infos); + mclcb->fsm.update_rx_state(mclcb, REVENT_CLOSE_RECV); + ASSERT(mclcb->fsm.no_new_adu(mclcb)); + if (mclcb->get_stats_level() >= 1) { + mclcb->stats.print_rx_stats(mclcb); + mclcb->stats.print_final_stats(mclcb); + } + break; + + default: + PRINT_ERR((mcl_stderr, + "mcl_rx_ctrl::process_cmd_pkt: ERROR, unknown type %d\n", + dhdr_infos.cmd_flavor)) +#ifdef DEBUG + mcl_exit(-1); +#else + goto bad_hdr; +#endif + } + + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl::process_cmd_pkt:\n")) + return MCL_OK; + + +bad_hdr: + mclcb->stats.bad_hdr++; + mclcb->stats.errors++; + delete pkt; // no du object yet, so free pkt explicitely + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_ctrl::process_cmd_pkt: ERROR, bad hdr\n")) + return MCL_ERROR; + +#ifdef NOT_YET +bad: + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_ctrl::process_cmd_pkt: ERROR\n")) + return MCL_ERROR; +#endif +} + + +/** + * timer callback method. + * @param arg1 mclcb + * @param arg2 pointer to an rx_ctrl_timer_event_t struct + */ +void +mcl_rx_ctrl::timer_callback (INT32 arg1, + INT32 arg2) +{ + mcl_cb *mclcb; // session of this event + mcl_rx_ctrl_tevent *tevent;// timer event + + /* + * WARNING, there is a risk that the mclcb context has disappeared + * when this function is called. Should check the validity of the + * mclcb arg quickly... + */ + mclcb = (mcl_cb*)arg1; + ASSERT(mclcb); + mclcb->lock(); + tevent = (mcl_rx_ctrl_tevent *)arg2; + ASSERT(tevent); + TRACELVL(5, (mcl_stdout, "-> mcl_rx_ctrl::timer_callback: %s\n", + tevent->get_type_string())) + /* + * Timer processing... + */ + switch (tevent->type) { + case RX_CTRL_TEVENT_START_NACK_PROCESS: { + mcl_rx_ctrl_NACK_tevent *te = (mcl_rx_ctrl_NACK_tevent*)tevent; + /* remove the tevent from the list first */ + if ((te->find_in_list(mclcb, &(this->NACK_tevent_head))) != NULL) { + ASSERT(te == te->find_in_list(mclcb, &(this->NACK_tevent_head))); + te->remove_from_list(mclcb, &(this->NACK_tevent_head)); + } + /* and then perform tevent processing */ + te->process(mclcb); + delete te; + break; + } + + case RX_CTRL_TEVENT_START_ACK_PROCESS: + break; + delete tevent; + + default: + ASSERT(0); + } + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl::timer_callback:\n")) + mclcb->unlock(); + return; + +#if 0 +bad: + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl::timer_callback: ERROR\n")) + mclcb->unlock(); + return; +#endif +} + + +#if 0 +/** + * Default constructor + */ +mcl_rx_ctrl_tevent::mcl_rx_ctrl_tevent (mcl_rx_ctrl_tevent_types t) +{ + this->type = t; +} +#endif + + +/** + * Default destructor + */ +mcl_rx_ctrl_tevent::~mcl_rx_ctrl_tevent () +{ +} + + +#ifdef DEBUG +/** + * Return the tevent type as a static string. + */ +char * +mcl_rx_ctrl_tevent::get_type_string () const +{ + // WARNING: must be compliant with mcl_rx_ctrl_tevent_types definition! + static char *type_strings[] = { + "RX_CTRL_TEVENT_INVALID", + "RX_CTRL_TEVENT_START_NACK_PROCESS", + "RX_CTRL_TEVENT_START_ACK_PROCESS" + }; + + return type_strings[this->type]; +} +#endif // DEBUG + + +/** + * Insert a tevent in an unordered list. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ +mcl_error_status +mcl_rx_ctrl_tevent::insert_in_list (mcl_cb *const mclcb, + mcl_rx_ctrl_tevent **head) +{ + ASSERT(head); + TRACELVL(5, (mcl_stdout, "-> mcl_rx_ctrl_tevent::insert_in_list:\n")) + if (!(*head)) { + /* + * first tevent in list + */ + *head = this; + this->next = this->prev = this; + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl_tevent::insert_in_list: ok, inserted in empty list\n")) + } else { + /* + * insert in list tail. + */ + this->next = *head; + this->prev = (*head)->prev; + (*head)->prev->next = this; + (*head)->prev = this; + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl_tevent::insert_in_list:\n")) + } + return MCL_OK; +} + + +/** + * Remove a tevent from an unordered list. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ +mcl_error_status +mcl_rx_ctrl_tevent::remove_from_list (mcl_cb *const mclcb, + mcl_rx_ctrl_tevent **head) +{ + mcl_rx_ctrl_tevent *p, *n; // temp prev and next pointers + + ASSERT(head); + TRACELVL(5, (mcl_stdout, "-> mcl_rx_ctrl_tevent::remove_from_list:\n")) + ASSERT(*head); + p = this->prev; + n = this->next; + if (p == this) { /* only one tevent in list */ + ASSERT(n == this); + *head = NULL; /* list is now empty */ + } else { + p->next = n; + n->prev = p; + if (*head == this) { + *head = n; /* adu was the first in list */ + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl_tevent::remove_from_list:\n")) + return MCL_OK; +} + + +/** + * Find a NACK_tevent in an unordered list with a type-dependant criteria. + * @param mclcb + * @param head pointer to the list head pointer + * @return returns a pointer to the tevent if found, NULL otherwise + */ +mcl_rx_ctrl_NACK_tevent * +mcl_rx_ctrl_NACK_tevent::find_in_list (mcl_cb *const mclcb, + mcl_rx_ctrl_tevent **head) +{ + mcl_rx_ctrl_NACK_tevent *tevent; + mcl_rx_ctrl_NACK_tevent *nhead; + + TRACELVL(5, (mcl_stdout, "-> mcl_rx_ctrl_tevent::find_in_list:\n")) + ASSERT(head); + if (!(nhead = (mcl_rx_ctrl_NACK_tevent*)(*head))) { + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_ctrl_tevent::find_in_list: empty list\n")) + return NULL; + } + /* + * start from the list tail + */ + tevent = (mcl_rx_ctrl_NACK_tevent*)(nhead->prev); + while (1) { + ASSERT(tevent); + if ((tevent->adu_id == this->adu_id) && + (tevent->block_id == this->block_id)) { + /* found */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_ctrl_tevent::find_in_list: found\n")) + return tevent; + } + if (tevent == nhead) { + /* we have cycled or new adu cannot be in list */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_ctrl_tevent::find_in_list: new\n")) + return NULL; + } + tevent = (mcl_rx_ctrl_NACK_tevent*)tevent->prev; + } +} + + +/** + * Default constructor. + */ +mcl_rx_ctrl_NACK_tevent::mcl_rx_ctrl_NACK_tevent (UINT32 adu_idf, + UINT32 block_idf, + mcl_addr *saddr) +{ + this->type = RX_CTRL_TEVENT_START_NACK_PROCESS; + this->prev = this->next = NULL; + this->adu_id = adu_idf; + this->block_id = block_idf; + this->src_addr = *saddr; +} + + +/** + * Default destructor. + */ +mcl_rx_ctrl_NACK_tevent::~mcl_rx_ctrl_NACK_tevent () +{ +} + + +/** + * Perform NACK_tevent specific processing. + */ +void +mcl_rx_ctrl_NACK_tevent::process (mcl_cb *const mclcb) +{ + mcl_adu *adu; + mcl_block *blk; + INT32 missing; // nb of missing DUs + norm_common_hdr_t *hdr; // norm header + INT32 hlen; // norm header length + mcl_addr sa; // remote address to which NACK + // must be sent + + TRACELVL(5, (mcl_stdout, "-> mcl_rx_ctrl_NACK_tevent::process:\n")) + /* find the adu first */ + if (!(adu = mclcb->rx_window.find_adu(mclcb, this->adu_id))) { + /* + * for some reason this ADU is not in rx window... + * maybe all packets of this ADU have been lost, so ask for + * a complete retransmission + */ + TRACELVL(5, (mcl_stdout, + " mcl_rx_ctrl_NACK_tevent::process: WARNING, adu %d not found in rx window\n", + this->adu_id)) +#if 0 + mclcb->stats.errors++; + PRINT_ERR((mcl_stderr, + "mcl_rx_ctrl_NACK_tevent::process: WARNING, adu %d not found in rx window\n", + this->adu_id)) + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_ctrl_NACK_tevent::process: WARNING, adu not found in rx window\n")) + return; +#endif + sa = this->src_addr; + missing = 1; // be conservative first! + } else { + /* + * normal case where the ADU is known... + */ + sa = adu->addr; + if (adu->check_if_completed(mclcb)) { + /* ADU already completed/decoded/delivered, no need + * to check further */ + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl_NACK_tevent::process: adu already completed\n")) + return; + } + /* find the block */ + if (!(blk = adu->find_block(mclcb, this->block_id))) { + /* + * for some reason this block is not in rx window + * whereas the ADU is know. + * This is a serious error, exit all! + */ + //TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl_NACK_tevent::process: block not found in rx window, ask for complete retx\n")) + PRINT_ERR((mcl_stdout, "mcl_rx_ctrl_NACK_tevent::process: ERROR, block not found in rx window\n")) + mcl_exit(-1); + } + /* and calculate how many DUs are missing */ + missing = blk->get_number_of_missing_dus(mclcb); + if (missing == 0) { + /* nothing to do */ + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_ctrl_NACK_tevent::process: block fully rx\n")) + return; + } + } + /* + * some DUs are still missing + * create and send a NACK packet... + */ + if ((hlen = mclcb->norm_pkt_mgmt.create_nack_hdr(mclcb, &hdr, + this->adu_id, this->block_id, missing)) <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_rx_ctrl_NACK_tevent::process: norm_pkt_mgmt.create_nak_hdr() failed\n")) + ASSERT(0); // in debug mode, stop immediately... + return; + } + /* + * send the NACK specifically to the source unicast address + */ + mclcb->ses_channel.send_pkt(mclcb, sa, hdr, hlen, NULL); + PRINT_LVL(1, (mcl_stdout, "\tNACK sent for blk %d/%d, %d missing\n", + this->adu_id, this->block_id, missing)) + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl_NACK_tevent::process: NACK sent\n")) + return; + +#if 0 +ask_for_complete_retx: + PRINT_ERR((mcl_stderr, "XXX: ERROR, TODO: ask for complete retx\n")) + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl_NACK_tevent::process:\n")) + ASSERT(0); // in debug mode, stop immediately... + return; +#endif +} + diff --git a/src/norm/mcl_rx_ctrl.h b/src/norm/mcl_rx_ctrl.h new file mode 100644 index 0000000..8c18f5f --- /dev/null +++ b/src/norm/mcl_rx_ctrl.h @@ -0,0 +1,253 @@ +/* $Id: mcl_rx_ctrl.h,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_RX_CTRL_H +#define MCL_RX_CTRL_H + + +/** + * Receiver's control tasks. + * This class is used for NORM control message reception and transmission + * (if applicable) at a receiver. + * This class inherits the timer_handler class in order to have a timer + * callback function. + */ +class mcl_rx_ctrl : public mcl_timer_handler { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + */ + mcl_rx_ctrl(); + + /** + * Process an incoming NORM_CMD packet. + * @param mclcb + * @param pkt pointer to packet + * @param saddr source address for this packet + * @param chdr_infos pointer to the common_infos struct + */ + mcl_error_status process_cmd_pkt (mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_addr *saddr, + mcl_common_hdr_infos_t *chdr_infos); + + /** + * timer callback method. + * @param arg1 mclcb + * @param arg2 pointer to an rx_ctrl_timer_event_t struct + */ + virtual void timer_callback (INT32 arg1, INT32 arg2); + + + /****** Public Attributes *********************************************/ + + /** + * + * @param XXX explanation + * @return Completion status (MCL_OK or MCL_ERROR). + */ + +protected: + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + + /** + * Create a list of pending timer_events. + * Required for instance to avoid duplicated timer_events, when + * receiving several instances of the same FLUSH command. + * There is one list per tevent type. + */ + class mcl_rx_ctrl_tevent *NACK_tevent_head; + //class mcl_rx_ctrl_tevent *ACK_tevent_head; + +}; + + +/** + * Types of timer events. + */ +enum mcl_rx_ctrl_tevent_types { + RX_CTRL_TEVENT_INVALID = 0, + RX_CTRL_TEVENT_START_NACK_PROCESS, + RX_CTRL_TEVENT_START_ACK_PROCESS +}; + + +/** + * This base class describes timer events. + * This is the second arg of timer_callback() method. + */ +class mcl_rx_ctrl_tevent { + +public: + /****** Public Members ************************************************/ + +#if 0 + /** + * Default constructor. + */ + mcl_rx_ctrl_tevent () = 0; +#endif + + /** + * Default destructor. + */ + virtual ~mcl_rx_ctrl_tevent (); + +#ifdef DEBUG + /** Return the tevent type as a static string. */ + char *get_type_string () const; +#endif + + /** + * Timer-specific processing function + */ + + /** + * Insert a tevent in an unordered list. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ + mcl_error_status insert_in_list (mcl_cb *const mclcb, + mcl_rx_ctrl_tevent **head); + + /** + * Remove a tevent from an unordered list. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ + mcl_error_status remove_from_list (mcl_cb *const mclcb, + mcl_rx_ctrl_tevent **head); + + + /****** Public Attributes *********************************************/ + + /** Control message type. */ + mcl_rx_ctrl_tevent_types type; + + +protected: + /****** Protected Members *********************************************/ + /****** Protected Attributes ******************************************/ + mcl_rx_ctrl_tevent *prev, *next; + + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + +}; + + +/** + * This class describes the NACK timer event. + * It is derived from the mcl_rx_ctrl_tevent base class. + */ +class mcl_rx_ctrl_NACK_tevent : public mcl_rx_ctrl_tevent { + +public: + /****** Public Members ************************************************/ + + /** + * Default constructor. + * @param adu_idf ADU for which this NACK_tevent pertains + * @param block_idf block within this ADU for which this + * NACK_tevent pertains + */ + mcl_rx_ctrl_NACK_tevent (UINT32 adu_idf, + UINT32 block_idf, + mcl_addr *saddr); + + /** + * Default destructor. + */ + virtual ~mcl_rx_ctrl_NACK_tevent (); + + /** + * Perform NACK_tevent specific processing. + */ + void process (mcl_cb *const mclcb); + + /** + * Find a NACK_tevent in an unordered list with type-dependant criteria. + * Compares the adu_id and block_id arguments. + * @param mclcb + * @param head pointer to the list head pointer + * @return returns a pointer to the tevent if found, NULL otherwise + */ + mcl_rx_ctrl_NACK_tevent *find_in_list (mcl_cb *const mclcb, + mcl_rx_ctrl_tevent **head); + + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + UINT32 adu_id; // used with NORM_CMD_FLUSH + UINT32 block_id; // used with NORM_CMD_FLUSH + /** + * Address of the sender of a control message. + * It is sometimes required to have it directly, e.g. if a ctrl + * msg is received for an ADU for which we didn't receive any + * packet yet (e.g. they have all been lost) + */ + mcl_addr src_addr; + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +#if 0 +inline mcl_error_status +mcl_rx_ctrl_NACK_tevent::insert_in_list (mcl_cb *const mclcb) +{ + return mcl_rx_ctrl_tevent::insert_in_list(mclcb, + &(mclcb->rx_ctrl->NACK_tevent_head)); +} + +inline mcl_error_status +mcl_rx_ctrl_NACK_tevent::remove_from_list (mcl_cb *const mclcb) +{ + return mcl_rx_ctrl_tevent::insert_in_list(mclcb, + &((mcl_rx_ctrl_tevent*)this->NACK_tevent_head)); +} + +inline mcl_rx_ctrl_NACK_tevent * +mcl_rx_ctrl_NACK_tevent::find_in_list (mcl_cb *const mclcb) +{ + return mcl_rx_ctrl_tevent::insert_in_list(mclcb, + &((mcl_rx_ctrl_tevent*)this->NACK_tevent_head)); +} +#endif + +#endif // MCL_RX_CTRL_H diff --git a/src/norm/mcl_rx_storage.cpp b/src/norm/mcl_rx_storage.cpp new file mode 100644 index 0000000..dd41cc9 --- /dev/null +++ b/src/norm/mcl_rx_storage.cpp @@ -0,0 +1,62 @@ +/* $Id: mcl_rx_storage.cpp,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + +/** + * Default constructor. + * Allocates the data buffer with the size provided. + * @param max_size the maximum packet size, including headers + */ +mcl_rx_pkt::mcl_rx_pkt (INT32 max_size) +{ + //ASSERT(max_size > (INT32)sizeof(norm_common_hdr_t)); + this->buf = new char[max_size]; + ASSERT(this->buf); + this->buf_len = max_size; + this->pkt_len = 0; +} + + +/** + * Default destructor. + * This destructor deletes both the pkt and the buffer, but NOT the DU + * (if any). + */ +mcl_rx_pkt::~mcl_rx_pkt () +{ + if (this->buf) { + delete [] this->buf; + this->buf = NULL; + } + this->buf_len = 0; + this->pkt_len = 0; +} + + +mcl_rx_storage::mcl_rx_storage() +{ +} + +mcl_rx_storage::~mcl_rx_storage() +{ +} + diff --git a/src/norm/mcl_rx_storage.h b/src/norm/mcl_rx_storage.h new file mode 100644 index 0000000..179e680 --- /dev/null +++ b/src/norm/mcl_rx_storage.h @@ -0,0 +1,131 @@ +/* $Id: mcl_rx_storage.h,v 1.3 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_RX_STORAGE +#define MCL_RX_STORAGE + + +/** + * Class that stores all the incoming packets. + */ +class mcl_rx_pkt { + +public: + /****** Public Members ************************************************/ + /** + * Default constructor. + * Allocates the data buffer with the size provided. + * @param max_size the maximum packet size, including headers + */ + mcl_rx_pkt (INT32 max_size); + + /** + * Default destructor. + * This destructor deletes both the pkt and the buffer, but NOT the DU + * (if any). + */ + ~mcl_rx_pkt (); + + /** + * Return a pointer to the buffer where the whole packet is stored + * @return pointer to buffer. + */ + char *get_buf (); + + /** + * Return the buffer length. + * The actual size of the packet stored is of course inferior or + * equal to this size. + * @return buffer legnth. + */ + INT32 get_buf_len (); + + /****** Public Attributes *********************************************/ + + /** + * Return the whole packet length, including headers. + */ + INT32 pkt_len; + + +private: + /****** Private Members ***********************************************/ + + /****** Private Attributes ********************************************/ + + /** + * Buffer where packet is stored. + * This buffer is allocated once, at creation. + */ + char *buf; + + /** + * Length of this buffer. + */ + INT32 buf_len; +}; + + +/** + * Class explanation + */ +class mcl_rx_storage { + +public: + /****** Public Members ************************************************/ + mcl_rx_storage(); + ~mcl_rx_storage(); + +#if 0 + /****** Public Attributes *********************************************/ + + /** + * + * @param XXX explanation + * @return Completion status (MCL_OK or MCL_ERROR). + */ + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ +#endif // 0 + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline char * +mcl_rx_pkt::get_buf () +{ + return this->buf; +} + +inline INT32 +mcl_rx_pkt::get_buf_len () +{ + return this->buf_len; +} + + +#endif // MCL_RX_STORAGE diff --git a/src/norm/mcl_rx_thread.cpp b/src/norm/mcl_rx_thread.cpp new file mode 100644 index 0000000..1e02cca --- /dev/null +++ b/src/norm/mcl_rx_thread.cpp @@ -0,0 +1,135 @@ +/* $Id: mcl_rx_thread.cpp,v 1.3 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + +mcl_rx_thread::mcl_rx_thread () +{ + rx_thread_id = 0; +} + + +mcl_rx_thread::~mcl_rx_thread () +{ +} + + +void +mcl_rx_thread::start (mcl_cb *const mclcb) +{ + /* + * create the timer thread... + */ +#ifdef WIN32 + if (CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) mcl_rx_thread::rx_thread, + NULL, 0, (LPDWORD)mclcb) == NULL) { + perror("mcl_rx_thread::start: CreateThread"); + mcl_exit(1); + } +#else + if (pthread_create((pthread_t*)&(this->rx_thread_id), + NULL, + mcl_rx_thread::rx_thread, + (void*)mclcb) != 0) { + perror("mcl_rx_thread::start: pthread_create"); + mcl_exit(1); + } +#endif +} + + +/** + * Reception thread. + * This thread polls data regularly on the various mcast groups... + */ +void * +mcl_rx_thread::rx_thread (void *arg) +{ + mcl_cb *mclcb = (mcl_cb*)arg; + + /* + * we don't sleep here but in the recv_pkt() func. + * the unlock will be done there... + */ + ASSERT(mclcb != NULL); + TRACELVL(5, (mcl_stdout, "-> RxThread:\n")) +#ifndef WIN32 + pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); + /* + * cancellation is deferred till next check point , i.e. points + * in code where we know everything is in a stable state + */ + pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL); + pthread_testcancel(); +#endif + mclcb->lock(); + while (1) { + if (mclcb->fsm.is_closed(mclcb)) { + /* everything is finished */ + break; + } + TRACELVL(6, (mcl_stdout, + "mcl_rx_thread::rx_thread: ses_id=%d, time_count=%d, state %s\n", + mclcb->get_id(), mcl_time_count, + mclcb->fsm.print_rx_state(mclcb))) + if (mclcb->is_a_receiver() && + mclcb->fsm.no_new_undup_du(mclcb)) { + /* + * we received all DUs... + * we now wait that the application finishes to read + * all data and issues a final mcl_close(). + */ + TRACELVL(6, (mcl_stdout, + "mcl_rx_thread::rx_thread: waiting final mcl_close() call\n")) + mclcb->unlock(); +#ifndef WIN32 + pthread_testcancel(); +#endif + mcl_usleep(DFLT_POLLING_PERIOD); +#ifndef WIN32 + pthread_testcancel(); +#endif + mclcb->lock(); + TRACELVL(6, (mcl_stdout, + "mcl_rx_thread::rx_thread: waiting final mcl_close() call\n")) + } else { + /* + * get new packets... + * this call is blocking, waiting new packets to arrive + */ + if (mclcb->ses_channel.recv_pkt(mclcb) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_rx_thread::rx_thread: recv_pkt failed\n")) + mcl_exit(-1); + + } + } + } + TRACELVL(5, (mcl_stdout, "<- RxThread:\n")) + mclcb->unlock(); + arg = 0; +#ifdef WIN32 + ExitThread(0); +#else + pthread_exit(arg); +#endif + return arg; /* unused */ +} + diff --git a/src/norm/mcl_rx_thread.h b/src/norm/mcl_rx_thread.h new file mode 100644 index 0000000..33ef743 --- /dev/null +++ b/src/norm/mcl_rx_thread.h @@ -0,0 +1,88 @@ +/* $Id: mcl_rx_thread.h,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_RX_THREAD_H +#define MCL_RX_THREAD_H + + +/** + * Reception thread of a given MCL session. + * This thread is in charge of listening to all reception sockets and + * calling the appropriate processing function each time a new packet + * arrives. + */ +class mcl_rx_thread { +public: + /****** Public Members ************************************************/ + mcl_rx_thread (); + ~mcl_rx_thread (); + + /** + * Starts the reception service. + * Exits in case of error. + */ + void start (class mcl_cb *const mclcb); + + /** + * Return the thread id. + * Required to enable a safe thread destruction. + */ + mcl_thread_t get_rx_thread_id (); + + /****** Public Attributes *********************************************/ + + /** + * + * @param XXX explanation + * @return Completion status (MCL_OK or MCL_ERROR). + */ + +private: + /****** Private Members ***********************************************/ + + /** + * Reception thread of the MCL session. + * This thread polls data regularly on the various mcast groups... + * Needs to be static since pthread_create() cannot be used with + * non-static member functions. + * @param arg mclcb session pointer + */ + static void *rx_thread (void *arg); + + + /****** Private Attributes ********************************************/ + mcl_thread_t rx_thread_id; // idf returned at creation + +}; + + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline mcl_thread_t +mcl_rx_thread::get_rx_thread_id() +{ + return rx_thread_id; +} + +#endif // MCL_RX_THREAD_H diff --git a/src/norm/mcl_rx_window.cpp b/src/norm/mcl_rx_window.cpp new file mode 100644 index 0000000..10983b8 --- /dev/null +++ b/src/norm/mcl_rx_window.cpp @@ -0,0 +1,250 @@ +/* $Id: mcl_rx_window.cpp,v 1.3 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * default constructor + */ +mcl_rx_window::mcl_rx_window () +{ + memset(this, 0, sizeof(*this)); + this->delivery_mode_to_appli = MCL_IMMEDIATE_DELIVERY; +} + + +/** + * default destructor + */ +mcl_rx_window::~mcl_rx_window () +{ + /* TODO: free all remaining ADUs and DUs... */ + memset(this, 0, sizeof(*this)); +} + + +/** + * Set the delivery mode. + */ +mcl_error_status +mcl_rx_window::set_delivery_mode_to_appli (mcl_cb *const mclcb, + mcl_delivery_mode_to_appli mode) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_cb::set_delivery_mode: %s", + (mode == MCL_IMMEDIATE_DELIVERY) ? "IMMEDIATE_DELIVERY" : + "ORDERED_DELIVERY")) + this->delivery_mode_to_appli = mode; + return MCL_OK; +} + + +#if 0 +/** + * Register a new FEC or data DU in the receiving window. + * @return Completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_rx_window::insert_du (mcl_cb *const mclcb, + mcl_du *const du) +{ + return MCL_OK; +} +#endif // 0 + +/** + * Process an incoming ADU announcement and insert it in the list. + * The ADU must not already be in list. + * @param mclcb + * @param hddr_infos structure containing the new ADU infos (plus + * many other info not used) + * @return completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_rx_window::process_adu_announcement + (mcl_cb *const mclcb, + mcl_addr * saddr, + mcl_data_hdr_infos_t * dhdr_infos) +{ + mcl_adu *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_rx_window::process_adu_announcement:\n")) + ASSERT(this->find_adu(mclcb, dhdr_infos->idf_adu) == NULL); + if (mclcb->get_verbosity() >= 1) { + mcl_print_recvd_du(mclcb, false, MCL_SIG_NEWADU, dhdr_infos); + } + /* + * completely new ADU. + * update the state first... + */ + if (mclcb->fsm.no_new_adu(mclcb) == true) { + /* + * no new ADU is expected, so check that the one announced + * has actually been implicitely announced, i.e. its idf is + * inferior or equal to the highest possible ADU id. + */ + if (dhdr_infos->max_idf_adu > mclcb->rx.get_highest_adu_seq_of_session()) { + /* error, FSM state update will fail... */ + mclcb->fsm.update_rx_state(mclcb, REVENT_NEW_ADU); + } /* else implicitely announced, do not update the FSM state */ + } else { + /* normal case, we are still expecting new ADUs */ + mclcb->fsm.update_rx_state(mclcb, REVENT_NEW_ADU); + } + /* + * allocate/init the adu and all of its constituting blocks... + */ + adu = new mcl_adu (mclcb, dhdr_infos, saddr); + /* + * insert the adu in the expected adu list + */ + this->insert_adu(mclcb, adu); + + mclcb->stats.adus_announced++; + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::process_adu_announcement:\n")) + return MCL_OK; +} + + +/** + * Check if all ADUs have been completed. + * @return boolean + */ +bool +mcl_rx_window::check_if_all_adu_completed (mcl_cb *const mclcb) +{ + mcl_adu *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_rx_window::check_if_all_adu_completed:\n")) + for (adu = this->adu_head->get_prev(); ; adu = adu->get_prev()) { + if (adu->get_rx_status() < ADU_STATUS_COMPLETED) { + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::check_if_all_adu_completed: no\n")) + return false; + } + if (adu == this->adu_head) { + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::check_if_all_adu_completed: yes\n")) + return true; + } + } +} + + +/** + * @return next ADU fully received and decoded, complying with the + * reception mode (IMMEDIATE_DELIVERY/ORDERED_DELIVERY) of + * the application, if any, NULL otherwise. + */ +mcl_adu * +mcl_rx_window::get_next_ready_adu (mcl_cb *const mclcb) +{ + mcl_adu *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_rx_window::get_next_ready_adu:\n")) + if (this->nb_of_ready_adu <= 0) { + /* nothing ready */ + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::get_next_ready_adu: no adu available\n")) + return NULL; + } + if (this->use_immediate_delivery_to_appli()) { + /* + * IMMEDIATE_DELIVERY + */ + /* + * there is necessarily a ready adu. + * search by increasing seq numbers, from the start... + */ + adu = this->adu_head; + do { + if (adu->get_rx_status() == ADU_STATUS_DECODED) { + /* found a ready adu */ + break; + } + adu = adu->get_next(); + } while (adu != this->adu_head); + ASSERT(adu->get_rx_status() == ADU_STATUS_DECODED); + } else { + /* + * ORDERED_DELIVERY + */ + ASSERT(0); // not yet implemented! +#if 0 // not yet implemented! + ASSERT(mclcb->ordered_delivery()); + if (this->next_ordered_adu_to_return != NULL) { + /* the next adu to return to appli is already known */ + adu = mclcb->rxlvl.next_adu2give; + ASSERT(adu->seq == seq); + if (adu->rx_status != ADU_STATUS_DECODED) { + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_window::get_next_ready_adu: next adu not ready (state=%d)\n", adu->rx_status)) + return -1; /* not ready */ + } + /* ready... continues after the else... */ + } else { + /* search for a ready adu in the list */ + for (adu = mclcb->rxlvl.adu_head->next; ; adu = adu->next) { + if (adu->seq == seq) { + /* found the next adu */ + if (adu->rx_status != ADU_STATUS_DECODED) { + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_window::get_next_ready_adu: next adu not ready 2 (state=%d)\n", adu->rx_status)) + mclcb->rxlvl.next_adu2give = adu; + return -1; /* not ready */ + } else { + break; /* ready */ + /* continues after the else...*/ + } + } + if (adu == mclcb->rxlvl.adu_head) { + /* we have cycled => no adu ready */ + TRACELVL(5, (mcl_stdout, "<- mcl_rx_window::get_next_ready_adu: next adu not found\n")) + return -1; + } + } + } +#endif // 0 + } + TRACELVL(5, (mcl_stdout, + "<- mcl_rx_window::get_next_ready_adu: found adu seq=%d\n", + adu->get_seq())) + return adu; +} + + +/** + * Update nb of ready adus plus the next adu to deliver info + * (ORDERED_DELIVERY) and change the ADU status to delivered. + */ +void +mcl_rx_window::mark_adu_delivered(mcl_adu *adu) +{ + this->nb_of_ready_adu--; + adu->set_rx_status(ADU_STATUS_DELIVERED); + + // TO DO ... +#if 0 + mclcb->rxlvl.next_adu2give_seq++; + if (n_adu && n_adu->seq == mclcb->rxlvl.next_adu2give_seq) { + mclcb->rxlvl.next_adu2give = n_adu; + } else { + mclcb->rxlvl.next_adu2give = NULL; + } +#endif +} diff --git a/src/norm/mcl_rx_window.h b/src/norm/mcl_rx_window.h new file mode 100644 index 0000000..484df25 --- /dev/null +++ b/src/norm/mcl_rx_window.h @@ -0,0 +1,272 @@ +/* $Id: mcl_rx_window.h,v 1.4 2004/06/29 10:31:35 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_RX_WINDOW_H +#define MCL_RX_WINDOW_H + + +/** Possible delivery modes of ADUs to the receiving application. */ +enum mcl_delivery_mode_to_appli { + MCL_IMMEDIATE_DELIVERY, + MCL_ORDERED_DELIVERY +}; + + +/** + * This class provides all the required services to manage the reception + * window at a receiver. + */ +class mcl_rx_window { + +public: + /****** Public Members ************************************************/ + /** + * default constructor + */ + mcl_rx_window (); + + /** + * default destructor + */ + ~mcl_rx_window (); + + /** + * Register a new ADU in the receiving window. + * @param mclcb + * @param adu + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status insert_adu (mcl_cb *const mclcb, + mcl_adu *const adu); + + /** + * Remove the ADU from the receiving window. + * @param mclcb + * @param adu + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status remove_adu (mcl_cb *const mclcb, + mcl_adu *const adu); + + /** + * Get the first ADU of the receiving window. + */ + mcl_adu *get_first_adu (mcl_cb *const mclcb); + + /** + * Get the last ADU of the receiving window. + */ + mcl_adu *get_last_adu (mcl_cb *const mclcb); + + /** + * Free all the ADUs of the receiving window. + * This function is only called at session close/abort. + */ + void free_all_adu (mcl_cb *const mclcb); + + /** + * Find an ADU in the receiving window with its sequence number. + * @param mclcb + * @param seq ADU seq number + * @return returns a pointer to the adu if found, NULL otherwise + */ + mcl_adu *find_adu (mcl_cb *const mclcb, + UINT32 idf_adu); + + /** + * Process an incoming ADU announcement and insert it in the list. + * The ADU must not already be in list. + * @param mclcb + * @param hddr_infos structure containing the new ADU infos (plus + * many other info not used) + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status process_adu_announcement + (mcl_cb *const mclcb, + mcl_addr * saddr, + mcl_data_hdr_infos_t * dhdr_infos); + + /** + * Check if all ADUs have been completed. + * @return boolean + */ + bool check_if_all_adu_completed (mcl_cb *const mclcb); + + /** + * Note that a new ADU is ready. + */ + void mark_ready_adu (); + + /** + * Is there an ADU ready to be returned to the appli? + */ + bool is_an_adu_ready (); + + /** + * Find the following ADU that can be returned to the receiving + * application. + * Warning, this function is read-only and does not change anything + * in the rx_window list nor does it mark the ADU as delivered! + * @return next ADU fully received and decoded, complying with the + * reception mode (IMMEDIATE_DELIVERY/ORDERED_DELIVERY) of + * the application, if any, NULL otherwise. + */ + mcl_adu *get_next_ready_adu (mcl_cb *const mclcb); + + /** + * Update nb of ready adus plus the next adu to deliver info + * (ORDERED_DELIVERY) and change the ADU status to delivered. + */ + void mark_adu_delivered(mcl_adu *adu); + + /** + * Register a new FEC or data DU in the receiving window. + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status insert_du (mcl_cb *const mclcb, + mcl_du *du); + + /** + * Does the receiver use an immediate delivery mode. + * @return boolean + */ + bool use_immediate_delivery_to_appli (void); + + /** + * Does the receiver use an ordered delivery mode. + * @return boolean + */ + bool use_ordered_delivery_to_appli (void); + + /** + * Set the delivery mode. + * @param mclcb + * @param mode delivery mode to set + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_delivery_mode_to_appli + (mcl_cb *const mclcb, + mcl_delivery_mode_to_appli mode); + + + + /****** Public Attributes *********************************************/ + + /** + * + * @param XXX explanation + * @return Completion status (MCL_OK or MCL_ERROR). + */ + bool postpone_fec_decoding;// decode during reception or at the end? + +private: + /****** Private Members ***********************************************/ + /** + * Insert a DU in the normal priority list. + * @param du data or FEC DU to insert + */ + void insert_in_list (mcl_cb *const mclcb, mcl_du *const du); + + /****** Private Attributes ********************************************/ + + /** head of ADU doubly linked list. */ + mcl_adu *adu_head; + + /** + * And here is the corresponding DU lists. + */ + /** DU list (du_list). */ + mcl_du *du_list_head; + //mcl_du *du_list_tail; + /** counter */ + INT32 nb_of_du_in_list; + + /** Number of ADUs been fully decoded and can be sent to the appli */ + INT32 nb_of_ready_adu; + + /* Immediate vs ordered_delivery of ADUs to the receiving appli. */ + mcl_delivery_mode_to_appli delivery_mode_to_appli; +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline mcl_error_status +mcl_rx_window::insert_adu (mcl_cb *const mclcb, + mcl_adu *const adu) +{ + return adu->insert_in_list(mclcb, &(this->adu_head)); +} + +inline mcl_error_status +mcl_rx_window::remove_adu (mcl_cb *const mclcb, + mcl_adu *const adu) +{ + return adu->remove_from_list(mclcb, &(this->adu_head)); +} + +inline mcl_adu * +mcl_rx_window::find_adu (mcl_cb *const mclcb, + UINT32 idf_adu) +{ + return this->adu_head->find_in_list(mclcb, this->adu_head, idf_adu); +} + +inline mcl_adu * +mcl_rx_window::get_first_adu (mcl_cb *const mclcb) +{ + return this->adu_head; +} + +inline mcl_adu * +mcl_rx_window::get_last_adu (mcl_cb *const mclcb) +{ + return ((this->adu_head != NULL) ? this->adu_head->get_prev() : NULL); +} + +inline void +mcl_rx_window::mark_ready_adu() +{ + nb_of_ready_adu++; +} + +inline bool +mcl_rx_window::is_an_adu_ready () +{ + return (nb_of_ready_adu > 0); +} + +inline bool +mcl_rx_window::use_immediate_delivery_to_appli () +{ + return (this->delivery_mode_to_appli == MCL_IMMEDIATE_DELIVERY); +} + +inline bool +mcl_rx_window::use_ordered_delivery_to_appli () +{ + return (this->delivery_mode_to_appli == MCL_ORDERED_DELIVERY); +} + +#endif // !MCL_RX_WINDOW_H + diff --git a/src/norm/mcl_ses_channel.cpp b/src/norm/mcl_ses_channel.cpp new file mode 100644 index 0000000..5e42153 --- /dev/null +++ b/src/norm/mcl_ses_channel.cpp @@ -0,0 +1,794 @@ +/* $Id: mcl_ses_channel.cpp,v 1.4 2004/06/15 15:53:27 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +mcl_ses_channel::mcl_ses_channel () +{ + struct sockaddr_in saddr; // temp storage of default session addr + + this->ses_sock = 0; + this->priv_sock = 0; + this->ttl = 1; + this->socket_size = MCL_DFLT_SOCKET_SIZE; + this->can_tx = false; + this->can_rx = false; + + this->is_mcast = -1; + FD_ZERO(&(this->fds)); + this->nfds = -1; + this->n_fd = 0; +#if defined(SIMUL_TX_LOSSES) || defined(SIMUL_RX_LOSSES) + this->simul_losses_state = 0; +#endif + + // default session addr init. + saddr.sin_family = AF_INET; + saddr.sin_port = htons(2323); + if (inet_aton("225.1.2.3", &(saddr.sin_addr)) == 0) { + perror("mcl_ses_channel::mcl_ses_channel: inet_aton"); + mcl_exit(1); + } + this->ses_addr.set_addr_struct(&saddr); +} + + +mcl_ses_channel::~mcl_ses_channel () +{ + this->ses_sock = 0; + this->priv_sock = 0; + this->can_tx = this->can_rx = false; + this->is_mcast = -1; +} + + +/** + * Sends a data or control packet on this channel. + */ +mcl_error_status +mcl_ses_channel::send_pkt (mcl_cb *const mclcb, + norm_common_hdr_t *const hdr, + INT32 const hlen, + mcl_du *const du) +{ + //mcl_addr a; + if (du) { + /* use the adu destination addr */ + //a = du->block->adu->addr; + //return (this->send_pkt(mclcb, &(du->block->adu->addr), + return (this->send_pkt(mclcb, du->block->adu->addr, + hdr, hlen, du)); + } else { + /* use the default destination addr */ + //a = &(mclcb->ses_channel.ses_addr); + //return (this->send_pkt(mclcb, &(mclcb->ses_channel.ses_addr), + return (this->send_pkt(mclcb, mclcb->ses_channel.ses_addr, + hdr, hlen, du)); + } +} + + +/** + * Sends a data or control packet on this channel. + * The destination address is specified and can be either a unicast + * or multicast address. + */ +mcl_error_status +mcl_ses_channel::send_pkt (mcl_cb *const mclcb, + //mcl_addr *const addr1, + mcl_addr const addr1, + norm_common_hdr_t *const hdr, + INT32 const hlen, + mcl_du *const du) +{ + mcl_adu *adu; + INT32 len; + MCL_IOVEC iov[2]; /* to describe header + data */ + struct sockaddr_in sa; + INT32 sa_len; +#ifdef WIN32 + struct sockaddr *msg_name; + u_int32_t msg_namelen; +#else + struct msghdr msg; /* for the sendmsg() Socket syscall */ +#endif + + TRACELVL(5, (mcl_stdout, "-> mcl_ses_channel::send_pkt:\n")) + /* + * update traces and statistics + */ + if (mclcb->get_verbosity() >= 2) { + mcl_print_sent_du(mclcb, du); + if (du && mclcb->get_verbosity() >= 4) { + /* header and data are in two diff buffers */ + mcl_dump_buffer(du->data, hlen, (hlen>> 2)); + } + } + if (du) { + adu = du->block->adu; + len = du->len; + } else { + adu = NULL; + len = 0; + } + if (len > 0) { + if (du->is_fec) { + mclcb->stats.tx_fec_pkts++; + mclcb->stats.tx_fec_bytes += len + hlen; + } else { + mclcb->stats.tx_data_pkts++; + mclcb->stats.tx_data_bytes += len + hlen; + } + } + mclcb->stats.tx_tot_pkts++; + mclcb->stats.tx_tot_bytes += len + hlen; + + /* + * prepare the iovec and the provided destination addr + */ + MCL_IOV_BUFF(iov[0]) = (MCL_IOV_BUFF_TYPE)hdr; + MCL_IOV_LEN(iov[0]) = hlen; + if (len > 0) { + ASSERT(du->data); + MCL_IOV_BUFF(iov[1]) = (MCL_IOV_BUFF_TYPE)du->data; + MCL_IOV_LEN(iov[1]) = len; + + } + //ASSERT(addr1); +#ifdef WIN32 + TODO +#else /* UNIX */ +#if 0 +printf("adu->addr = x%x\n", (int)&(adu->addr)); +printf("adu->addr = %s\n", adu->addr.get_addr_string()); +printf("addr = x%x\n", (int)addr1); +printf("port = %d\n", addr1->get_port()); +printf("addr = %s\n", addr1->get_addr_string()); +#endif + memset(&msg, 0, sizeof(msg)); + addr1.get_addr_struct(&sa); + sa_len = sizeof(sa); + msg.msg_name = (char*)&sa; + msg.msg_namelen = sa_len; + + msg.msg_iov = iov; + msg.msg_iovlen = (len > 0 ? 2 : 1); +#endif /* OS_DEP */ + + /* + * and now send the packet + */ +#ifdef SIMUL_TX_LOSSES + if (this->sim_random_loss(mclcb) == false) { + /* no simulated loss, tx can take place */ +#endif /* SIMUL_TX_LOSSES */ +#ifdef WIN32 + if (WSASendTo(mclcb->ses_channel.priv_sock, iov, (len > 0 ? 2 : 1), NULL, 0, + msg_name, msg_namelen, NULL, NULL) == 0) { + /* + * if (mclcb->verbose == 2) + * malloc_stats(); + */ + perror("mcl_ses_channel::send_pkt: sendmsg"); + mcl_exit(1); + } +#else /* UNIX */ + if (sendmsg(mclcb->ses_channel.priv_sock, &msg, 0) != hlen + len) { + /* + * if (mclcb->verbose == 2) + * malloc_stats(); + */ + perror("mcl_ses_channel::send_pkt: sendmsg"); + mcl_exit(1); + } +#endif /* OS_DEP */ + + if (mclcb->get_verbosity() >= 4) { +#ifdef WIN32 + PRINT_OUT((mcl_stdout, + "sendmsg: priv_sock=%d, dst=%s/%d, hdr_len=%d, payload_len=%d\n", + mclcb->ses_channel.priv_sock, + inet_ntoa(((struct sockaddr_in*)msg_name)->sin_addr), + ntohs(((struct sockaddr_in*)msg_name)->sin_port), + hlen, len)) +#else /* UNIX */ + PRINT_OUT((mcl_stdout, + "sendmsg: priv_sock=%d, dst=%s/%d, hdr_len=%d, payload_len=%d\n", + mclcb->ses_channel.priv_sock, + inet_ntoa(((struct sockaddr_in*)(msg.msg_name))->sin_addr), + ntohs(((struct sockaddr_in*)(msg.msg_name))->sin_port), + hlen, len)) +#endif /* OS_DEP */ + } +#ifdef SIMUL_TX_LOSSES + } else { + /* lost... */ + TRACELVL(3, (mcl_stdout, " mcl_ses_channel:send_pkt: loss simulated\n")) + } +#endif /* SIMUL_TX_LOSSES */ + + TRACELVL(5, (mcl_stdout, "<- mcl_ses_channel::send_pkt:\n")) + return MCL_OK; +} + + +/** + * Receive a data or control packet on this channel. + * @param mclcb + * @return Completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_ses_channel::recv_pkt (mcl_cb *const mclcb) +{ + mcl_rx_pkt *pkt; // recv'd packet buffer + struct sockaddr saddr; // buffer for src addr + INT32 saddr_len; // buffer for src addr len + mcl_addr addr; // class for src addr + INT32 n; + fd_set tmp_fds; + struct timeval tv; // don't wait indefinitely in select + + TRACELVL(5, (mcl_stdout, "-> mcl_ses_channel::recv_pkt:\n")) +again: + /* + * wait to receive packets... a select on several fd is required! + */ + if (this->n_fd == 0) { + /* + * nothing to select; wait a bit and return... + */ + mclcb->unlock(); +#ifndef WIN32 + pthread_testcancel(); +#endif + mcl_usleep(DFLT_POLLING_PERIOD); +#ifndef WIN32 + pthread_testcancel(); +#endif + mclcb->lock(); + TRACELVL(5, (mcl_stdout, "<- mcl_ses_channel::recv_pkt: no fd to listen\n")) + return MCL_OK; + } + tmp_fds = this->fds; + tv.tv_sec = 1; /* wait at most 1s to have opportunity to update fds */ + tv.tv_usec = 0; + mclcb->unlock(); +#ifndef WIN32 + pthread_testcancel(); +#endif + if ((n = select(this->nfds, &tmp_fds, NULL, NULL, &tv)) < 0) { + /* + * in practice always try again, without trying to + * differentiate on type of error (usually select has + * been interrupted...) + */ + mclcb->lock(); + goto again; + } +#ifndef WIN32 + pthread_testcancel(); +#endif + mclcb->lock(); + if (n == 0) { + /* nothing received */ + TRACELVL(5, (mcl_stdout, "<- mcl_ses_channel::recv_pkt: timeout\n")) + return MCL_OK; + } + /* + * read the packet(s) received (there may be more than one!) + */ + //if (n>0) printf("select returned n=%d\n", n); + //if (this->ses_sock > 0 && FD_ISSET(this->ses_sock, &tmp_fds)) { + /* XXX: doing so, a source ignores mcast packets sent by receivers! + * Change it when the filtering problem is solved */ + if (mclcb->is_a_receiver() && + this->ses_sock > 0 && FD_ISSET(this->ses_sock, &tmp_fds)) { + while (this->ses_sock > 0) { + pkt = new mcl_rx_pkt(mclcb->get_max_datagram_size()); + ASSERT(pkt); + saddr_len = sizeof(saddr); + memset(&saddr, 0, sizeof(saddr)); + if ((pkt->pkt_len = recvfrom(this->ses_sock, + pkt->get_buf(), pkt->get_buf_len(), + 0, &saddr, +#ifndef SOLARIS /* linux: uint, solaris: int */ + (size_t*) +#endif + &saddr_len)) < 0) { + /* we are in non-blocking mode! */ +#ifdef SOLARIS /* cannot check errno reliably on Solaris! don't know why!!! */ + /* XXX: assume no ready packet anymore*/ + delete pkt; + break; + +#elif defined(WIN32) + if (WSAGetLastError() == WSAEWOULDBLOCK) { + /* no ready packet anymore */ + delete pkt; + break; + } +#else /* LINUX */ + if (errno == EAGAIN || errno == EWOULDBLOCK) { + /* no ready packet anymore */ + delete pkt; + break; + } +#endif /* OS */ + +#ifdef WIN32 + TRACELVL(5, (mcl_stdout, " mcl_ses_channel::recv_pkt: ERROR, ses_sock=%d, error=%d\n", this->ses_sock, WSAGetLastError())) +#else /* UNIX */ + TRACELVL(5, (mcl_stdout, " mcl_ses_channel::recv_pkt: ERROR, ses_sock=%d, error=%d\n", this->ses_sock, errno)) +#endif + perror("mcl_ses_channel::recv_pkt: recvfrom"); + mcl_exit(1); + } + addr.set_addr_struct((struct sockaddr_in*)&saddr); +#if 0 + /* drop packets that we sent ourselves! */ + if (addr.is_equal(mclcb->ses_channel.priv_addr)) { + TRACELVL(5, (mcl_stdout, + " mcl_ses_channel::recv_pkt: dropped (sent by us)\n")) + delete pkt; + break; + } +#endif + /* and finally process the packet */ + mclcb->rx.process_pkt(mclcb, pkt, &addr); + /* + * try again... + */ + break; + } + } + if (this->priv_sock > 0 && FD_ISSET(this->priv_sock, &tmp_fds)) { + while (this->ses_sock > 0) { + pkt = new mcl_rx_pkt(mclcb->get_max_datagram_size()); + ASSERT(pkt); + saddr_len = sizeof(saddr); + memset(&saddr, 0, sizeof(saddr)); + if ((pkt->pkt_len = recvfrom(this->priv_sock, + pkt->get_buf(), pkt->get_buf_len(), + 0, &saddr, +#ifndef SOLARIS /* linux => uint, solaris => int */ + (size_t*) +#endif + &saddr_len)) < 0) { + + + /* we are in non-blocking mode! */ +#ifdef SOLARIS /* cannot check errno reliably on Solaris! don't know why!!! */ + /* XXX: assume no ready packet anymore*/ + delete pkt; + break; + +#elif defined(WIN32) + if (WSAGetLastError() == WSAEWOULDBLOCK) { + /* no ready packet anymore */ + delete pkt; + break; + } +#else /* LINUX */ + if (errno == EAGAIN || errno == EWOULDBLOCK) { + /* no ready packet anymore */ + delete pkt; + break; + } +#endif /* OS */ + +#ifdef WIN32 + TRACELVL(5, (mcl_stdout, " mcl_ses_channel::recv_pkt: ERROR, priv_sock=%d, error=%d\n", this->priv_sock, WSAGetLastError())) +#else /* UNIX */ + TRACELVL(5, (mcl_stdout, " mcl_ses_channel::recv_pkt: ERROR, priv_sock=%d, error=%d\n", this->priv_sock, errno)) +#endif + perror("mcl_ses_channel::recv_pkt: recvfrom"); + mcl_exit(1); + } + addr.set_addr_struct((struct sockaddr_in*)&saddr); + /* and finally process the packet */ + mclcb->rx.process_pkt(mclcb, pkt, &addr); + /* + * try again... + */ + break; + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_ses_channel::recv_pkt: \n")) + return MCL_OK; +} + + +#if defined(SIMUL_TX_LOSSES) || defined(SIMUL_RX_LOSSES) +/** + * Simulate packets losses randomly + * Returns false if OK, true if packet should be lost... + */ +bool +mcl_ses_channel::sim_random_loss(mcl_cb *const mclcb) +{ + bool is_lost = false; + + TRACELVL(5, (mcl_stdout, "-> mcl_ses_channel::sim_random_loss:\n")) + switch (this->simul_losses_state) { + case 0: /* last packet was sent OK. */ +#ifdef CONSTANT_LOSS_RATIO + if ((float)(random()%100) < (float)P_LOSS_WHEN_OK) { +#else + TODO... +#endif + is_lost = true; + this->simul_losses_state = 1; + } + break; + case 1: /* last packet was lost */ +#ifdef CONSTANT_LOSS_RATIO + if ((float)(random()%100) < (float)P_LOSS_WHEN_LOSSES) { +#else + TODO... +#endif + is_lost = true; + } + else + this->simul_losses_state = 0; + break; + default: + perror("mcl_ses_channel::sim_random_loss:: unknown state"); + mcl_exit(1); + break; + } + TRACELVL(5, (mcl_stdout, "<- mcl_ses_channel::sim_random_loss: %s\n", + (is_lost ? "lost" : "ok"))) + if (is_lost) + mclcb->stats.tx_simul_loss_lost++; + else + mclcb->stats.tx_simul_loss_sent++; + return is_lost; +} +#endif /* SIMUL_XX_LOSSES */ + + +bool +mcl_ses_channel::is_mcast_session() +{ + if (this->is_mcast < 0) { + if (this->ses_addr.is_multicast_addr()) { + this->is_mcast = 1; + } else { + this->is_mcast = 0; + } + } + return (bool)this->is_mcast; +} + + +/* + * Performs the socket initialization work + * @param mclcb + * @param saddr session address (unicast or mcast) + */ +mcl_error_status +mcl_ses_channel::sock_init (mcl_cb *const mclcb) +{ + /* solaris seems to care about the int/char type, not linux! */ +#ifdef WIN32 + UINT32 mcast_ttl; /* for setsockopt */ +// UINT8 mcast_loop; +#else + UINT8 mcast_ttl; /* for setsockopt */ + UINT8 mcast_loop; +#endif /* OS_DEP */ + + UINT32 reuse_addr; /* for setsockopt */ + struct ip_mreq imr; /* ... to join mcast group */ + struct in_addr if_addr; /* interface IP address */ + struct sockaddr_in tmp_addr; /* temporary addr */ + INT32 tmp_len; /* temporary addr length */ + INT32 sock_size; /* socket size */ + INT32 mode = 0; // tx/rx mode + + TRACELVL(5, (mcl_stdout, "-> mcl_ses_channel::sock_init:\n")) + /* + * Step 1: determine the exact mode. + */ + if (mclcb->is_a_sender()) { + mode |= MODE_SIG_UNI_TX; + mode |= MODE_SIG_UNI_RX; + if (this->ses_addr.is_multicast_addr()) { + mode |= MODE_MCAST_TX; + mode |= MODE_SIG_MCAST_TX; + mode |= MODE_SIG_MCAST_RX; + } else { + mode |= MODE_UNI_TX; + } + } + if (mclcb->is_a_receiver()) { + mode |= MODE_SIG_UNI_RX; + mode |= MODE_SIG_UNI_TX; + if (this->ses_addr.is_multicast_addr()) { + mode |= MODE_MCAST_RX; + mode |= MODE_SIG_MCAST_TX; + mode |= MODE_SIG_MCAST_RX; + } else { + mode |= MODE_UNI_RX; + } + } + + if (this->mcast_if_addr) + if_addr.s_addr = htonl(this->mcast_if_addr->get_addr()); + else + if_addr.s_addr = htonl(INADDR_ANY); + + /* + * Step 2: initialize the private socket + */ + if ((mode & MODE_UNI_TX) || (mode & MODE_MCAST_TX) || + (mode & MODE_SIG_UNI_TX) || (mode & MODE_SIG_UNI_RX) || + (mode & MODE_SIG_MCAST_TX)) { + this->can_tx = 1; + /* + * private socket is always used for tx. + * required both by mcast traffic source and receivers + * (signaling) + */ + if ((this->priv_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("mcl_ses_channel::sock_init: socket"); + goto error; + } + if (mode & MODE_SIG_UNI_RX) { + /* + * priv_sock is also used for rx of signaling. + * This is required both by the sender (who receives + * unicast signaling) + * and by receivers (who also receive unicast responses + * from the sender) + */ + this->can_rx = 1; + /* + * For the future select(). + */ + FD_SET((UINT32)this->priv_sock, &(this->fds)); + this->nfds = max(this->nfds, this->priv_sock + 1); + this->n_fd++; + } + /* + * bind with 0 to get a locally unique port number + */ + tmp_addr.sin_family = AF_INET; + tmp_addr.sin_port = htons(0); + tmp_addr.sin_addr.s_addr = htonl(INADDR_ANY); +#ifdef WIN32 + if (bind(this->priv_sock, (struct sockaddr FAR *)&tmp_addr, + sizeof (tmp_addr)) == SOCKET_ERROR) +#else /* UNIX */ + if (bind(this->priv_sock, (struct sockaddr *)&tmp_addr, + sizeof(tmp_addr)) < 0) +#endif /* WIN32 */ + { + perror("mcl_ses_channel::sock_init: bind() Error"); + goto error; + } + } + + if ((mode & MODE_MCAST_TX) || (mode & MODE_SIG_MCAST_TX)) { + if (this->mcast_if_addr) { + /* specify multicast interface */ + if (setsockopt(this->priv_sock, IPPROTO_IP, + IP_MULTICAST_IF, + (char*)&if_addr.s_addr, + sizeof(if_addr.s_addr)) < 0) { + perror("mcl_ses_channel::sock_init (sender): IP_MULTICAST_IF"); + goto error; + } + } + /* specify ttl */ + mcast_ttl = min(this->ttl, 255); + if (setsockopt(this->priv_sock, IPPROTO_IP, IP_MULTICAST_TTL, + (char *)&mcast_ttl, sizeof(mcast_ttl)) < 0 ) { + perror("mcl_ses_channel::sock_init (sender): IP_MULTICAST_TTL"); + goto error; + } +#ifndef WIN32 + /* + * turn on the loop back of multicast packets to enable + * receivers local to this host to get data + */ + mcast_loop = 1; + if (setsockopt(this->priv_sock, IPPROTO_IP, IP_MULTICAST_LOOP, + (char *)&mcast_loop, sizeof(mcast_loop)) != 0) { + perror("mcl_ses_channel::sock_init (sender): IP_MULTICAST_LOOP"); + goto error; + } +#endif /* NOT WIN32 */ + } + /* + * finally store in priv_addr the allocated local addr/port number + * of priv_sock + */ + memset(&tmp_addr, 0, sizeof(tmp_addr)); + tmp_len = sizeof(tmp_addr); + if (this->priv_sock > 0 && + getsockname(this->priv_sock, (struct sockaddr *)&tmp_addr, +#ifndef SOLARIS + (size_t*) /* linux => uint, solaris => int */ +#endif + &tmp_len) < 0) { + perror("mcl_ses_channel::sock_init: getsockname"); + goto error; + } + if (this->mcast_if_addr && (this->mcast_if_addr->get_addr() != 0)) { + // use this addr since we are on a multihomed host and + // mcast_if the interface being used... + this->priv_addr = *(this->mcast_if_addr); + } else { + struct in_addr a; + // XXX: TODO: find default if addr... (in the meantime use 0) + if (inet_aton("0.0.0.0", &a) < 0) + perror("mcl_ses_channel::sock_init: inet_aton"); + this->priv_addr.set_addr(ntohl(a.s_addr)); + } + // tmp_addr contains the local port number... + this->priv_addr.set_port(ntohs(tmp_addr.sin_port)); + // and mcast_if contains the local address + //this->priv_addr.set_addr(this->mcast_if.get_addr()); + + /* + * Step 3: initialize the session socket + */ + if ((mode & MODE_UNI_RX) || (mode & MODE_MCAST_RX) || + (mode & MODE_SIG_MCAST_RX)) { + /* session socket is always used for mcast rx */ + if ((this->ses_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("mcl_ses_channel::sock_init: socket"); + goto error; + } + /* set non-blocking mode for future read on the session sock */ +#ifdef WIN32 + { + unsigned long NonBlocking = 1; + if (ioctlsocket(mg->ses_sock, FIONBIO, &NonBlocking) == SOCKET_ERROR ) { + perror("mcl_ses_channel::sock_init: fcntl"); + goto error; + } + } +#else + if (fcntl(this->ses_sock, F_SETFL, O_NONBLOCK) < 0) { + perror("mcl_ses_channel::sock_init: fcntl"); + goto error; + } +#endif + /* increase the default socket size */ + sock_size = this->socket_size; + if (setsockopt(this->ses_sock, SOL_SOCKET, SO_RCVBUF, (char*)&sock_size, sizeof(sock_size)) < 0) { + perror("mcl_ses_channel::sock_init: SO_RCVBUF"); + goto error; + } + /* for the future select() */ + if (mclcb->is_a_receiver()) { + /* XXX: doing so, a source ignores mcast packets sent + * by receivers! + * Change it when the filtering problem is solved */ + FD_SET((UINT32)this->ses_sock, &(this->fds)); + this->nfds = max(this->nfds, this->ses_sock + 1); + this->n_fd++; + } + + /* allow for reuse of the couple addr/port */ + reuse_addr = 1; + if (this->is_mcast_session() && + setsockopt(this->ses_sock, SOL_SOCKET, SO_REUSEADDR, + (char *)&reuse_addr, sizeof(reuse_addr)) < 0) { + perror("mcl_ses_channel::sock_init (recv): REUSEADDR"); + goto error; + } + /* now bind the session port number (with INADDR_ANY addr) */ + // memcpy(&tmp_addr, saddr, sizeof(*saddr)); + tmp_addr.sin_family = AF_INET; + tmp_addr.sin_port = htons(this->ses_addr.get_port()); + tmp_addr.sin_addr.s_addr = htonl(INADDR_ANY); + if (bind(this->ses_sock, (struct sockaddr*)&tmp_addr, + sizeof(tmp_addr)) < 0) { + perror("mcl_ses_channel::sock_init (recv): bind"); + PRINT_ERR((mcl_stderr, + "mcl_ses_channel::sock_init (recv): ERROR; bind to %s/%d failed\n", + inet_ntoa(tmp_addr.sin_addr), + ntohs(tmp_addr.sin_port))) + goto error; + } + } + + if ((mode & MODE_MCAST_RX) || (mode & MODE_SIG_MCAST_RX)) { + if (this->mcast_if_addr) { + /* specify multicast interface */ + if (setsockopt(this->ses_sock, IPPROTO_IP, + IP_MULTICAST_IF, + (char*)&if_addr.s_addr, + sizeof(if_addr.s_addr)) < 0) { + perror("mcl_ses_channel::sock_init (recv): IP_MULTICAST_IF"); + goto error; + } + } +#if 0 // USELESS + /* loop back multicast packets */ + +#ifndef WIN32 + mcast_loop = 1; + if (setsockopt(this->ses_sock, IPPROTO_IP, IP_MULTICAST_LOOP, + (char *)&mcast_loop, sizeof(mcast_loop)) != 0) { + perror("mcl_ses_channel::sock_init (recv): IP_MULTICAST_LOOP"); + goto error; + } +#endif /* NOT WIN32 */ +#endif + + /* multicast join */ + imr.imr_multiaddr.s_addr = htonl(this->ses_addr.get_addr()); + imr.imr_interface.s_addr = if_addr.s_addr; + + if (setsockopt(this->ses_sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, + (char *)&imr, sizeof(imr)) < 0) { + perror("mcl_ses_channel::sock_init (recv): IP_ADD_MEMBERSHIP"); + goto error; + } + } + + if (mclcb->get_verbosity() >= 4) { + // NB: use several print_out since get_addr_string() (and + // more fondamentally inet_ntoa()) is not reentrant! + PRINT_OUT((mcl_stdout, + "mcl_ses_channel::sock_init: ses_sock=%d (%s/%d),", + this->ses_sock, this->ses_addr.get_addr_string(), + this->ses_addr.get_port())) + PRINT_OUT((mcl_stdout, " priv_sock=%d (%s/%d)\n", + this->priv_sock, this->priv_addr.get_addr_string(), + this->priv_addr.get_port())) + } + TRACELVL(5, (mcl_stdout, "<- mcl_ses_channel::sock_init:\n")) + return MCL_OK; + +error: + TRACELVL(5, (mcl_stdout, "<- mcl_ses_channel::sock_init: failed\n")) + return MCL_ERROR; +} + + +/** + * Close all the remaining sockets. + */ +mcl_error_status +mcl_ses_channel::sock_close (mcl_cb *const mclcb) +{ + if ((this->priv_sock > 0 && close(this->priv_sock)) < 0) { + perror("mcl_ses_channel::sock_close: close on priv_sock"); + goto error; + } + if ((this->ses_sock > 0 && close(this->ses_sock)) < 0) { + perror("mcl_ses_channel::sock_close: close on ses_sock"); + goto error; + } + TRACELVL(5, (mcl_stdout, "<- mcl_ses_channel::sock_close:\n")) + return MCL_OK; + +error: + TRACELVL(5, (mcl_stdout, "<- mcl_ses_channel::sock_close: failed\n")) + return MCL_ERROR; +} + diff --git a/src/norm/mcl_ses_channel.h b/src/norm/mcl_ses_channel.h new file mode 100644 index 0000000..d7a9216 --- /dev/null +++ b/src/norm/mcl_ses_channel.h @@ -0,0 +1,184 @@ +/* $Id: mcl_ses_channel.h,v 1.4 2004/06/15 15:53:27 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef SESSION_CHANNEL_H +#define SESSION_CHANNEL_H + +/** + * Session channel class. + * Maintains information for the session channel, i.e. everything that + * is required to send or receive data or control packets. + * + * Two sockets are required: + * 1- the session socket, bound to the public mcast address/port + * 2- the private socket, bound to a private locally unique port number + * + * The SESSION socket is used for: + * - reception by a receiver of multicast packets (data or signaling) + * sent by the source + * - reception by a source of multicast signaling packets sent by a + * receiver + * + * The PRIVATE socket is used for: + * - all unicast or multicast transmissions by a source (data or signaling) + * - all unicast or multicast transmissions by a receiver (signaling) + * - reception by a source of unicast signaling packets sent by a receiver + * - reception by a receiver of unicast signaling response sent by a source + */ +class mcl_ses_channel { + +public: + /****** Public Members ************************************************/ + + /** The default constructor. */ + mcl_ses_channel (); + + /** The destructor. */ + ~mcl_ses_channel (); + + /** + * Easy way to know if the session uses a multicast addr or not. + * Prefer this function to a call to ses_addr.is_multicast_addr() + * since it is faster and simpler. + * @return boolean, true if the session addr is a multicast addr + */ + bool is_mcast_session (); + + /** + * Perform all the socket level initialization work for both the + * private and session sockets. + * Uses the various parameters already initialized with default + * values or with appropriate mcl_ctl() calls. + * @param mclcb + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status sock_init (mcl_cb *const mclcb); + + /** + * Close all the opened sockets if any. + */ + mcl_error_status sock_close (mcl_cb *const mclcb); + + /** + * Sends a data or control packet on this channel. + * Use the ADU destination addr, otherwise the default session address. + * Always uses the private socket. + * @param mclcb + * @param hdr header pointer + * @param hlen header length + * @param du data unit to send. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status send_pkt (mcl_cb *const mclcb, + norm_common_hdr_t *const hdr, + INT32 const hlen, + mcl_du *const du); + + /** + * Sends a data or control packet on this channel. + * The destination address is specified and can be either a unicast + * or multicast address. + * @param mclcb + * @param addr destination address + * @param hdr header pointer + * @param hlen header length + * @param du data unit to send. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status + mcl_ses_channel::send_pkt (mcl_cb *const mclcb, + //mcl_addr *const addr, + mcl_addr const addr, + norm_common_hdr_t *const hdr, + INT32 const hlen, + mcl_du *const du); + + /** + * Receive a data or control packet on this channel. + * Considers both the session and private sockets. + * @param mclcb + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status recv_pkt (mcl_cb *const mclcb); + + + /****** Public Attributes *********************************************/ + MCL_SOCKET ses_sock; // session socket: mcast rx + MCL_SOCKET priv_sock; // private sock: mcast/uni tx, uni rx + class mcl_addr ses_addr; // mcast address on session socket + char *mcast_if_name; // name of mcast interf. to use or NULL + class mcl_addr *mcast_if_addr; // addr of mcast interf. to use or NULL + class mcl_addr priv_addr; // our own addr from which we tx pkts + + UINT8 ttl; // ttl to use in case of mcast channel + INT32 socket_size; // size to use for tx and rx sockets + + bool can_tx; // true when initialized for tx + bool can_rx; // true when initialized for rx + + +private: + /****** Private Members ***********************************************/ + +#if defined(SIMUL_TX_LOSSES) || defined(SIMUL_RX_LOSSES) + /** + * Simulate packets losses randomly + * @return true if packet should be lost, false if pkt can be sent, + */ + bool mcl_ses_channel::sim_random_loss(mcl_cb *const mclcb); +#endif + + + /****** Private Attributes ********************************************/ + INT32 is_mcast; // -1 before first call to + // is_mcast_session(), 0 or 1 after + /* + * Select specific variables + */ + fd_set fds; // set of file descript, used by select + INT32 nfds; // highest-numbered fd, plus 1 + INT32 n_fd; // total nb of fd (ie sockets) + +#if defined(SIMUL_TX_LOSSES) || defined(SIMUL_RX_LOSSES) + INT32 simul_losses_state; +#endif +}; + + +/* + * tx/rx modes + * differentiate application mode and signalization mode (usually piggy-backed) + */ +#define MODE_UNI_TX 0x01 /* can send data in unicast */ +#define MODE_MCAST_TX 0x02 /* can send data in multicast */ +#define MODE_UNI_RX 0x04 /* can receive data in unicast */ +#define MODE_MCAST_RX 0x08 /* can receive data in multicast */ +#define MODE_SIG_UNI_TX 0x10 /* can send signaling in unicast */ +#define MODE_SIG_MCAST_TX 0x20 /* can send signaling in unicast */ +#define MODE_SIG_UNI_RX 0x40 /* can recv signaling in unicast */ +#define MODE_SIG_MCAST_RX 0x80 /* can recv signaling in unicast */ + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +#endif // !SESSION_CHANNEL_H diff --git a/src/norm/mcl_stats.cpp b/src/norm/mcl_stats.cpp new file mode 100644 index 0000000..fbf6b41 --- /dev/null +++ b/src/norm/mcl_stats.cpp @@ -0,0 +1,213 @@ +/* $Id: mcl_stats.cpp,v 1.4 2005/01/11 13:12:39 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +mcl_stats::mcl_stats () +{ + memset(this, 0, sizeof(*this)); +} + + +mcl_stats::~mcl_stats () +{ +} + + +/* + * Print sending side statistics + */ +void +mcl_stats::print_tx_stats (const mcl_cb *const mclcb) +{ + struct timeval tv; + + //ASSERT(mclcb->get_stats_level() > 0); + tv = mcl_get_tvtime(); + PRINT_OUT((stdout, "\n--- TX STATISTICS at t={%d,%d} ---\n", + (int)tv.tv_sec, (int)tv.tv_usec)) + PRINT_OUT((mcl_stdout, "\ttx_bytes=%u retx_bytes=%u tx_fec_bytes=%u tx_sig_bytes=%u\n", + this->tx_data_bytes, this->tx_retx_bytes, + this->tx_fec_bytes, this->tx_sig_bytes)) + PRINT_OUT((mcl_stdout, "\ttx_pkts =%u retx_pkts =%u tx_fec_pkts =%u tx_sig_pkts =%u\n", + this->tx_data_pkts, this->tx_retx_pkts, + this->tx_fec_pkts, this->tx_sig_pkts)) + PRINT_OUT((mcl_stdout, "\tData+SIG: tot_snt=%u tot_rx=%u bytes\n\tbuf_space=%u max_buf_space=%u adu_announced=%u\n", + this->tx_tot_bytes, this->rx_tot_bytes, + this->buf_space, this->max_buf_space, + this->adus_announced)) +#if defined(SIMUL_TX_LOSSES) || defined(SIMUL_RX_LOSSES) + if (this->tx_simul_loss_sent > 0) { + PRINT_OUT((mcl_stdout, "\tsimul_losses: lost=%u loss_ratio=%.3f\n", + this->tx_simul_loss_lost, + (float)this->tx_simul_loss_lost/(float)this->tx_simul_loss_sent)) + } +#endif +} + + +void +mcl_stats::print_rx_stats (const mcl_cb *const mclcb) +{ + struct timeval tv; + + //ASSERT(mclcb->get_stats_level() > 0); + tv = mcl_get_tvtime(); + PRINT_OUT((stdout, "\n--- RX STATISTICS at t={%d,%d} ---\n", + (int)tv.tv_sec, (int)tv.tv_usec)) + PRINT_OUT((mcl_stdout, "\tADUs completed/announced: %u / %u\n", + this->adus_completed, this->adus_announced)) + /* + * Byte stats + */ + PRINT_OUT((mcl_stdout, "\trx_bytes=%u rx_fec_bytes=%u including dup_bytes=%u\n", + this->rx_data_bytes, this->rx_fec_bytes, this->rx_dupl_bytes)) + /* + * Packet stats + */ + PRINT_OUT((mcl_stdout, "\trx_pkts=%u rx_fec_pkts=%u including dup_pkts=%u lost_pkts=%u\n\tdup/rx=%.3f rx/undup=%.2f\n", + this->rx_data_pkts, this->rx_fec_pkts, + this->rx_dupl_pkts, this->rx_lost_pkts, + (float)this->rx_dupl_pkts / (float)(this->rx_data_pkts + this->rx_fec_pkts), + (float)(this->rx_data_pkts + this->rx_fec_pkts) / (float)(this->rx_data_pkts + this->rx_fec_pkts - this->rx_dupl_pkts))) + PRINT_OUT((mcl_stdout, "\tData+SIG: tot_snt=%u tot_rx=%u bytes\n\tbuf_space=%u max_buf_space=%u\n\terrors=%u adu_announced=%u adu_completed=%u\n", + this->tx_tot_bytes, this->rx_tot_bytes, + this->buf_space, this->max_buf_space, + this->errors, + //this->bad_demux_label, + this->adus_announced, this->adus_completed)) +} + + +/* + * End of reception stats + */ +void +mcl_stats::print_final_stats (const mcl_cb *const mclcb) +{ + INT32 i; + + PRINT_OUT((mcl_stdout, "\n--- END OF RX TIMES ---\n")) + + i = this->finish_index - 1; + if (i < 0) + i = MAX_FIN_TIME - 1; + do { + ASSERT(i >= 0 && i < MAX_FIN_TIME); + if (this->finish_times[i][STATS_FIN_TIME] == 0 && + this->finish_times[i][STATS_SEQ] == 0) + return; + PRINT_OUT((mcl_stdout, "\t\tADU seq=%d time=%d\n", + (int)this->finish_times[i][STATS_SEQ], + (int)this->finish_times[i][STATS_FIN_TIME])) + i--; + if (i < 0) + i = MAX_FIN_TIME - 1; + } while (i != this->finish_index); +} + + +void +mcl_print_sent_du (mcl_cb *const mclcb, + //common_norm_hdr_t *hdr, + mcl_du *const du) +{ + if (!du) { + PRINT_OUT((mcl_stdout, "CMD pkt time=%d\n", mcl_time_count)) + return; + } + if (mclcb->get_verbosity() == 2) { + /* + * produce traces for timely analysis + */ + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tpkt_sent aseq=%d bseq=%d dseq=%d %s\n", + time.tv_sec, time.tv_usec, + du->block->adu->get_seq(), du->block->seq, du->seq, + (du->is_fec ? "fec" : "data"))) + } else if (mclcb->get_verbosity() >= 3) { + PRINT_OUT((mcl_stdout, + "pkt time=%d aseq=%d/bseq=%d/dseq=%d/%s\n", + mcl_time_count, + du->block->adu->get_seq(), du->block->seq, du->seq, + (du->is_fec ? "fec" : "data"))) + } +} + + +void +mcl_print_recvd_du (mcl_cb *const mclcb, + bool is_data, + UINT32 val, // add info, eg NEW_ADU, CLOSE + mcl_data_hdr_infos_t *dhdr_infos) +{ + if (mclcb->get_verbosity() <= 0) + return; + if (is_data) { + switch (mclcb->get_verbosity()) { + case 1: + /* + * produce traces for standard compact analysis + */ + PRINT_OUT((mcl_stdout, "\t%s %d/%d/%d\n", + (dhdr_infos->is_fec ? "fec " : "data"), + dhdr_infos->idf_adu, + dhdr_infos->idf_block, dhdr_infos->idf_du)) + + break; + case 2: + /* + * produce traces for timely analysis + */ + struct timeval time; + time = mcl_get_tvtime(); + PRINT_OUT((mcl_stdout, "\n%ld.%06ld\tpkt_rcvd aseq=%d bseq=%d dseq=%d %s\n", + time.tv_sec, time.tv_usec, + dhdr_infos->idf_adu, + dhdr_infos->idf_block, dhdr_infos->idf_du, + (dhdr_infos->is_fec ? "fec" : "data"))) + break; + default: + /* + * produce traces for detailed analysis + */ + PRINT_OUT((mcl_stdout, + "pkt time=%d aseq=%d/bseq=%d/dseq=%d/%s\n", + mcl_time_count, dhdr_infos->idf_adu, + dhdr_infos->idf_block, dhdr_infos->idf_du, + (dhdr_infos->is_fec ? "fec" : "data"))) + break; + } + } else if (val == MCL_SIG_NEWADU) { + PRINT_OUT((mcl_stdout, "New ADU (%d: %d bytes, %d blocks)\n", + dhdr_infos->idf_adu, dhdr_infos->adu_len, + (int)ceil((double)dhdr_infos->adu_len / + (double)dhdr_infos->block_len))) + } else if (val == MCL_SIG_NONEWADU) { + PRINT_OUT((mcl_stdout, "No New ADU (seq: %d to ?)\n", mcl_iss)) + //PRINT_OUT((mcl_stdout, "No New ADU (seq: %d to %d)\n", + // mcl_iss, dhdr_infos->max_idf_adu)) + } else if (val == MCL_SIG_CLOSE) { + PRINT_OUT((mcl_stdout, "\nClose\n")) + } +} diff --git a/src/norm/mcl_stats.h b/src/norm/mcl_stats.h new file mode 100644 index 0000000..a18507f --- /dev/null +++ b/src/norm/mcl_stats.h @@ -0,0 +1,144 @@ +/* $Id: mcl_stats.h,v 1.4 2005/01/11 13:12:39 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_STATS_H +#define MCL_STATS_H + + +/* + * statistics collected at the receiver and sender sides + */ +#define MAX_FIN_TIME 512 + +#define STATS_FIN_TIME 0 +#define STATS_SEQ 1 + + +/** + * Statistics class. + */ +class mcl_stats { + +public: + /****** Public Members ************************************************/ + mcl_stats (); + ~mcl_stats (); + + void print_tx_stats (const mcl_cb *const mclcb); + void print_rx_stats (const mcl_cb *const mclcb); + void print_final_stats (const mcl_cb *const mclcb); + + /****** Public Attributes *********************************************/ + + /* + * outgoing traffic stats + * NB: byte counters include both data and NORM headers + */ + UINT32 tx_data_pkts; /* nb of data packets sent */ + /* (doesn't include fec or retx pkts) */ + UINT32 tx_data_bytes; /* nb of data bytes sent*/ + /* (doesn't include fec or retx pkts) */ + UINT32 tx_retx_pkts; /* nb of data pkts re-transmited */ + UINT32 tx_retx_bytes; /* nb of data bytes sent*/ + UINT32 tx_sig_pkts; /* signaling only packets sent*/ + UINT32 tx_sig_bytes; /* nb signaling bytes sent */ + UINT32 tx_fec_pkts; /* nb of fec data pkts sent */ + UINT32 tx_fec_bytes; /* total nb of fec bytes sent */ + UINT32 tx_tot_pkts; /* total data/sig/fec pkts sent */ + UINT32 tx_tot_bytes; /* total data/sig/fec bytes sent */ +#if defined(SIMUL_TX_LOSSES) || defined(SIMUL_RX_LOSSES) + UINT32 tx_simul_loss_sent; /* total nb of non lost pkts */ + UINT32 tx_simul_loss_lost; /* total nb of simul lost pkts*/ +#endif + /* + * incoming traffic stats + * NB: byte counters include both data and NORM headers + */ + UINT32 rx_data_pkts; /* total nb of packets recvd */ + /* (doesn't include fec or retx pkts) */ + UINT32 rx_data_bytes; /* nb of data bytes received */ + /* (doesn't include fec or retx pkts) */ + UINT32 rx_sig_pkts; /* signaling only packets recvd */ + UINT32 rx_sig_bytes; /* nb signaling bytes recvd */ + UINT32 rx_fec_pkts; /* nb of fec pkts recvd */ + UINT32 rx_fec_bytes; /* nb of fec bytes recvd */ + UINT32 rx_undup_pkts; /* unduplicated pkts recvd */ + UINT32 rx_dupl_pkts; /* # pkts recvd several times */ + UINT32 rx_dupl_bytes; /* # bytes recvd several times*/ + UINT32 rx_tot_pkts; /* total data/sig/fec pkts recvd */ + UINT32 rx_tot_bytes; /* total data/sig/fec bytes recvd */ + + UINT32 rx_lost_pkts; /* total nb of lost pkts */ + + ushort finish_index; /* next available entry in tab*/ + UINT32 finish_times[MAX_FIN_TIME][2]; /* circular buffer of finish */ + /* times [][0] & seq nb [][1] */ + UINT32 adus_completed; /* nb of ADUs completed */ + /* + * errors + */ + UINT32 errors; /* nb of erroneous DUs recvd */ + UINT32 bad_hdr; /* error in header */ + //UINT32 bad_demux_label; /* wrong LCT demux label */ + UINT32 other_errors; /* non packet related errors */ + /* + * common stats + */ + UINT32 buf_space; /* current allocated buf space*/ + UINT32 max_buf_space; /* max allocated buffer space */ + UINT32 adus_announced; /* nb of ADUs announced */ + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + +}; + + +/** + * Print a sent DU in an understandable way. + * @param mclcb + * @param type + * @param val + * @param hdr_infos pointer to the header_info structure, that contains + * all the information concerning the sent DU. + */ +extern void mcl_print_sent_du (class mcl_cb *const mclcb, + class mcl_du *const du); + +/** + * Print a received DU in an understandable way. + * @param mclcb + * @param type + * @param val + * @param hdr_infos pointer to the header_info structure, that contains + * all the information concerning a recevied DU. + */ +extern void mcl_print_recvd_du (class mcl_cb *const mclcb, + bool is_data, UINT32 val, + struct mcl_data_hdr_infos *dhdr_infos); + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +#endif // !MCL_STATS_H diff --git a/src/norm/mcl_timer.cpp b/src/norm/mcl_timer.cpp new file mode 100644 index 0000000..f26fbb5 --- /dev/null +++ b/src/norm/mcl_timer.cpp @@ -0,0 +1,763 @@ +/* $Id: mcl_timer.cpp,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * contains code derived from: + */ +//============================================================================ +// Copyright (c) 1997-2001 TASC, Inc. +// Copyright (c) 1997-2001 University of Massachusetts at Amherst +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All advertising materials mentioning features or use of this software +// must display the following acknowledgement: +// This product includes software developed by TASC, Inc. and the +// University of Massachusetts at Amherst. +// 4. The names of TASC, Inc. and the University of Massachusetts at Amherst +// may not be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS +// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +//---------------------------------------------------------------------------- + +#include "mcl_includes.h" + + +// +// Static class members. +// + +bool mcl_timer::initialized = false; +INT32 mcl_timer::array_size = 0; +INT32 mcl_timer::scan_size = 0; +bool* mcl_timer::in_use = NULL; +struct timeval* mcl_timer::exp_time = NULL; +mcl_timer_handler** mcl_timer::object = NULL; +INT32* mcl_timer::argument1 = NULL; +INT32* mcl_timer::argument2 = NULL; +mcl_THREAD_ATTR_TYPE mcl_timer::timer_attr; +mcl_THREAD_TYPE mcl_timer::timer_thread; +mcl_MUTEX_TYPE mcl_timer::timer_mutex = mcl_MUTEX_CONST_INIT; +bool mcl_timer::timer_mutex_init = false; + + +//============================================================================ +mcl_error_status +mcl_timer::set_timer(UINT32 msec, mcl_timer_handler* obj, INT32 arg1, + INT32 arg2) +{ + char* mn = "set_timer"; + struct timeval tv; + INT32 i; + + // + // Synchronize the threads. + // + + if (!mcl_timer::timer_mutex_init) + { + mcl_MUTEX_STATIC_INIT(&mcl_timer::timer_mutex); + mcl_timer::timer_mutex_init = true; + } + + mcl_MUTEX_LOCK(&mcl_timer::timer_mutex); + + // + // If the timer class has not been initialized yet, call start(). + // + + if (!mcl_timer::initialized) + { + mcl_timer::start(); + + if (!mcl_timer::initialized) + { + log(mn, "Timer thread start failure."); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return(MCL_ERROR); + } + } + + // + // Add the timer information to the first open array element. + // + + for (i = 0; i < mcl_timer::array_size; i++) + { + if (!mcl_timer::in_use[i]) + { + +#ifdef GETTIMEOFDAY_NULL_ARG + if (gettimeofday(&tv, NULL) != 0) +#else + if (gettimeofday(&tv) != 0) +#endif + { + log(mn, "Unable to get current time."); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return(MCL_ERROR); + } + + tv.tv_sec += (msec / 1000); + tv.tv_usec += ((msec % 1000) * 1000); + + tv.tv_sec += (tv.tv_usec / 1000000); + tv.tv_usec = (tv.tv_usec % 1000000); + + mcl_timer::in_use[i] = true; + mcl_timer::exp_time[i] = tv; + mcl_timer::object[i] = obj; + mcl_timer::argument1[i] = arg1; + mcl_timer::argument2[i] = arg2; + + // + // Update the scan size. + // + + if (i >= mcl_timer::scan_size) + { + mcl_timer::scan_size = (i + 1); + } + + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return(MCL_OK); + } + } + + log(mn, "No room in timer array."); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return(MCL_ERROR); +} + +//============================================================================ +void mcl_timer::cancel_timer(mcl_timer_handler* obj) +{ + char* mn = "cancel_timer"; + INT32 i; + + // + // Synchronize the threads. + // + + if (!mcl_timer::timer_mutex_init) + { + mcl_MUTEX_STATIC_INIT(&mcl_timer::timer_mutex); + mcl_timer::timer_mutex_init = true; + } + + mcl_MUTEX_LOCK(&mcl_timer::timer_mutex); + + // + // If the timer class has not been initialized yet, call start(). + // + + if (!mcl_timer::initialized) + { + mcl_timer::start(); + + if (!mcl_timer::initialized) + { + log(mn, "Timer thread start failure."); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return; + } + } + + // + // Find all of the timer entries for the callback object and delete them. + // + + for (i = 0; i < mcl_timer::array_size; i++) + { + if (mcl_timer::in_use[i]) + { + if (mcl_timer::object[i] == obj) + { + mcl_timer::in_use[i] = false; + } + } + } + + // + // Update the scan size. + // + + for (i = (mcl_timer::array_size - 1); i >= 0; i--) + { + if (mcl_timer::in_use[i]) + { + mcl_timer::scan_size = (i + 1); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return; + } + } + + mcl_timer::scan_size = 0; + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); +} + +//============================================================================ +void mcl_timer::cancel_timer(mcl_timer_handler* obj, INT32 arg1) +{ + char* mn = "cancel_timer"; + INT32 i; + + // + // Synchronize the threads. + // + + if (!mcl_timer::timer_mutex_init) + { + mcl_MUTEX_STATIC_INIT(&mcl_timer::timer_mutex); + mcl_timer::timer_mutex_init = true; + } + + mcl_MUTEX_LOCK(&mcl_timer::timer_mutex); + + // + // If the timer class has not been initialized yet, call start(). + // + + if (!mcl_timer::initialized) + { + mcl_timer::start(); + + if (!mcl_timer::initialized) + { + log(mn, "Timer thread start failure."); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return; + } + } + + // + // Find all of the timer entries for the callback object and argument and + // delete them. + // + + for (i = 0; i < mcl_timer::array_size; i++) + { + if (mcl_timer::in_use[i]) + { + if ((mcl_timer::object[i] == obj) && + (mcl_timer::argument1[i] == arg1)) + { + mcl_timer::in_use[i] = false; + } + } + } + + // + // Update the scan size. + // + + for (i = (mcl_timer::array_size - 1); i >= 0; i--) + { + if (mcl_timer::in_use[i]) + { + mcl_timer::scan_size = (i + 1); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return; + } + } + + mcl_timer::scan_size = 0; + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); +} + +#if 0 +//============================================================================ +void mcl_timer::cancel_timer(mcl_timer_handler* obj, INT32 arg1, INT32 arg2) +{ + char* mn = "cancel_timer"; + INT32 i; + + // + // Synchronize the threads. + // + + if (!mcl_timer::timer_mutex_init) + { + mcl_MUTEX_STATIC_INIT(&mcl_timer::timer_mutex); + mcl_timer::timer_mutex_init = true; + } + + mcl_MUTEX_LOCK(&mcl_timer::timer_mutex); + + // + // If the timer class has not been initialized yet, call start(). + // + + if (!mcl_timer::initialized) + { + mcl_timer::start(); + + if (!mcl_timer::initialized) + { + log(mn, "Timer thread start failure."); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return; + } + } + + // + // Find all of the timer entries for the callback object and argument and + // delete them. + // + + for (i = 0; i < mcl_timer::array_size; i++) + { + if (mcl_timer::in_use[i]) + { + if ((mcl_timer::object[i] == obj) && + (mcl_timer::argument1[i] == arg1) && + (mcl_timer::argument2[i] == arg2)) + { + mcl_timer::in_use[i] = false; + } + } + } + + // + // Update the scan size. + // + + for (i = (mcl_timer::array_size - 1); i >= 0; i--) + { + if (mcl_timer::in_use[i]) + { + mcl_timer::scan_size = (i + 1); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return; + } + } + + mcl_timer::scan_size = 0; + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); +} +#endif + +//============================================================================ +mcl_error_status +mcl_timer::cancel_timer(mcl_timer_handler* obj, INT32 arg1, INT32 arg2) +{ + char* mn = "cancel_timer"; + INT32 i; + bool found = false; // indicates if at least one instance has been found + + // + // Synchronize the threads. + // + + if (!mcl_timer::timer_mutex_init) + { + mcl_MUTEX_STATIC_INIT(&mcl_timer::timer_mutex); + mcl_timer::timer_mutex_init = true; + } + + mcl_MUTEX_LOCK(&mcl_timer::timer_mutex); + + // + // If the timer class has not been initialized yet, call start(). + // + + if (!mcl_timer::initialized) + { + mcl_timer::start(); + + if (!mcl_timer::initialized) + { + log(mn, "Timer thread start failure."); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return MCL_ERROR; + } + } + + // + // Find all of the timer entries for the callback object and argument and + // delete them. + // + + for (i = 0; i < mcl_timer::array_size; i++) + { + if (mcl_timer::in_use[i]) + { + if ((mcl_timer::object[i] == obj) && + (mcl_timer::argument1[i] == arg1) && + (mcl_timer::argument2[i] == arg2)) + { + mcl_timer::in_use[i] = false; + found = true; + } + } + } + + // + // Update the scan size. + // + + for (i = (mcl_timer::array_size - 1); i >= 0; i--) + { + if (mcl_timer::in_use[i]) + { + mcl_timer::scan_size = (i + 1); + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return (found ? MCL_OK : MCL_ERROR); + } + } + + mcl_timer::scan_size = 0; + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + return (found ? MCL_OK : MCL_ERROR); +} + +//============================================================================ +void mcl_timer::nap(UINT32 msec) +{ + struct timeval tv; + + // + // If the nap time is less than one millisecond, return. + // + + if (msec < 1) + { + return; + } + + // + // Use select() as a fairly portable way to sleep with subsecond precision. + // + tv.tv_sec = (msec / 1000); + tv.tv_usec = ((msec % 1000) * 1000); + + select(0, NULL, NULL, NULL, &tv); +} + +//============================================================================ +void mcl_timer::yield_processor() +{ + + // + // Yield the CPU. + // + + mcl_THREAD_YIELD(); +} + +//============================================================================ +void mcl_timer::kill_thread() +{ + INT32 i; + + // + // If a timer thread is running, cancel it and clear out the timer arrays. + // + + if (mcl_timer::initialized) + { + + // + // Synchronize the threads. + // + + if (!mcl_timer::timer_mutex_init) + { + mcl_MUTEX_STATIC_INIT(&mcl_timer::timer_mutex); + mcl_timer::timer_mutex_init = true; + } + + mcl_MUTEX_LOCK(&mcl_timer::timer_mutex); + + for (i = 0; i < MCL_TIMER_ARRAY_SIZE; i++) + { + mcl_timer::in_use[i] = false; + mcl_timer::exp_time[i].tv_sec = 0; + mcl_timer::exp_time[i].tv_usec = 0; + mcl_timer::object[i] = NULL; + mcl_timer::argument1[i] = 0; + mcl_timer::argument2[i] = 0; + } + + mcl_THREAD_KILL(mcl_timer::timer_thread); + + mcl_timer::initialized = false; + + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + } + + mcl_THREAD_YIELD(); +} + +//============================================================================ +void mcl_timer::start() +{ + char* mn = "start"; + INT32 i; + + // + // Allocate the arrays. + // + + if (mcl_timer::in_use == NULL) + { + mcl_timer::in_use = new bool[MCL_TIMER_ARRAY_SIZE]; + + if (mcl_timer::in_use == NULL) + { + log(mn, "Unable to allocate in_use array."); + return; + } + } + + if (mcl_timer::exp_time == NULL) + { + mcl_timer::exp_time = new struct timeval[MCL_TIMER_ARRAY_SIZE]; + + if (mcl_timer::exp_time == NULL) + { + log(mn, "Unable to allocate expiration time array."); + return; + } + } + + if (mcl_timer::object == NULL) + { + mcl_timer::object = new mcl_timer_handler*[MCL_TIMER_ARRAY_SIZE]; + + if (mcl_timer::object == NULL) + { + log(mn, "Unable to allocate object array."); + return; + } + } + + if (mcl_timer::argument1 == NULL) + { + mcl_timer::argument1 = new INT32[MCL_TIMER_ARRAY_SIZE]; + + if (mcl_timer::argument1 == NULL) + { + log(mn, "Unable to allocate fist argument array."); + return; + } + } + + if (mcl_timer::argument2 == NULL) + { + mcl_timer::argument2 = new INT32[MCL_TIMER_ARRAY_SIZE]; + + if (mcl_timer::argument2 == NULL) + { + log(mn, "Unable to allocate second argument array."); + return; + } + } + + // + // Initialize the sizes and array elements. + // + + mcl_timer::array_size = MCL_TIMER_ARRAY_SIZE; + mcl_timer::scan_size = 0; + + for (i = 0; i < MCL_TIMER_ARRAY_SIZE; i++) + { + mcl_timer::in_use[i] = false; + mcl_timer::exp_time[i].tv_sec = 0; + mcl_timer::exp_time[i].tv_usec = 0; + mcl_timer::object[i] = NULL; + mcl_timer::argument1[i] = 0; + mcl_timer::argument2[i] = 0; + } + + // + // Create the timer thread. Make it a detached thread. + // + + if (mcl_THREAD_ATTR_INIT(&mcl_timer::timer_attr) != 0) + { + log(mn, "Thread attribute initialization error."); + return; + } + + if (mcl_THREAD_ATTR_SETDETACHSTATE(&mcl_timer::timer_attr, + mcl_CONST_CREATE_DETACHED) != 0) + { + log(mn, "Thread set attribute detached state error."); + return; + } + + if (mcl_THREAD_CREATE(&mcl_timer::timer_thread, &mcl_timer::timer_attr, + mcl_timer::run, NULL) != 0) + { + log(mn, "Thread creation error."); + return; + } + + if (mcl_THREAD_ATTR_DESTROY(&mcl_timer::timer_attr) != 0) + { + log(mn, "Thread attribute destruction error."); + return; + } + + // + // Mark the initialization as complete. + // + + mcl_timer::initialized = true; +} + +//============================================================================ +mcl_VOID_METHOD mcl_timer::run(mcl_THREAD_ARG arg) +{ + struct timeval tv; + bool forever; + bool retry; + mcl_timer_handler* localObject; + INT32 lastState; + INT32 lastType; + INT32 localArgument1; + INT32 localArgument2; + INT32 i; + + // + // Set deferred cancelation for this thread. + // + + mcl_THREAD_CANCEL_STATE(mcl_CONST_CANCEL_ENABLE, &lastState); + mcl_THREAD_CANCEL_TYPE(mcl_CONST_CANCEL_DEFERRED, &lastType); + + // + // Block the SIGINT signal in this thread. + // + + mcl_SIGNAL_BLOCK_MASK(SIGINT); + + // + // Loop forever. + // + + forever = true; + + while (forever) + { + mcl_timer::yield_processor(); + + // + // Sleep for some amount of time using either sginap() or select(). + // + + mcl_THREAD_TEST_CANCEL(); + +#ifdef HAVE_SGINAP + sginap((50 * CLK_TCK) / 1000); +#else + tv.tv_sec = 0; + tv.tv_usec = 50000; + + select(0, NULL, NULL, NULL, &tv); +#endif + + mcl_THREAD_TEST_CANCEL(); + + // + // Get the current time and perform any callbacks that are due. Be sure + // to aquire the mutex lock whenever accessing the static members. + // However, the mutex lock cannot be held when actually performing any + // callbacks. Also, the loop that checks for expired timers must be + // restarted after each callback since a callback might set or cancel + // timers. + // + +#ifdef GETTIMEOFDAY_NULL_ARG + if (gettimeofday(&tv, NULL) == 0) +#else + if (gettimeofday(&tv) == 0) +#endif + { + mcl_MUTEX_LOCK(&mcl_timer::timer_mutex); + + retry = true; + + while (retry) + { + retry = false; + + for (i = 0; i < mcl_timer::scan_size; i++) + { + if (mcl_timer::in_use[i]) + { + if ((tv.tv_sec > mcl_timer::exp_time[i].tv_sec) || + ((tv.tv_sec == mcl_timer::exp_time[i].tv_sec) && + (tv.tv_usec >= mcl_timer::exp_time[i].tv_usec))) + { + if (mcl_timer::object[i] != NULL) + { + localObject = mcl_timer::object[i]; + localArgument1 = mcl_timer::argument1[i]; + localArgument2 = mcl_timer::argument2[i]; + + mcl_timer::in_use[i] = false; + + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + localObject->timer_callback(localArgument1, localArgument2); + mcl_MUTEX_LOCK(&mcl_timer::timer_mutex); + + retry = true; + break; + } + } + } + } + } + + mcl_MUTEX_UNLOCK(&mcl_timer::timer_mutex); + } + } + + return(NULL); +} + +//============================================================================ +void mcl_timer::log(char* mn, char* s) +{ + cerr << "[mcl_timer::" << mn << "] " << s << endl; +} diff --git a/src/norm/mcl_timer.h b/src/norm/mcl_timer.h new file mode 100644 index 0000000..1e302e1 --- /dev/null +++ b/src/norm/mcl_timer.h @@ -0,0 +1,234 @@ +/* $Id: mcl_timer.h,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * contains code derived from: + */ +//============================================================================ +// Copyright (c) 1997-2001 TASC, Inc. +// Copyright (c) 1997-2001 University of Massachusetts at Amherst +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All advertising materials mentioning features or use of this software +// must display the following acknowledgement: +// This product includes software developed by TASC, Inc. and the +// University of Massachusetts at Amherst. +// 4. The names of TASC, Inc. and the University of Massachusetts at Amherst +// may not be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS +// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + +#ifndef MCL_TIMER_H +#define MCL_TIMER_H + +#include "mcl_timer_handler.h" + +/** + * Class that provides static methods that allow events to be timed, resulting + * in callbacks. This class runs as a seperate thread and is itself thread- + * safe. Timers may be set when inside of timer callbacks. + * @version $Revision: 1.2 $ + * @author Mark Keaton + */ +class mcl_timer { + +public: + + /** + * Create a timer for an event. When at least the amount of time specified + * elapses, the TimerCallback() method of the specified object is called + * passing the specified arguments. + * @param msec The number of milliseconds to time. + * @param obj The callback object. + * @param arg1 The first callback argument. + * @param arg2 The second callback argument. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + static mcl_error_status set_timer(UINT32 msec, mcl_timer_handler* obj, + INT32 arg1, INT32 arg2); + + /** + * Cancels all timers that are currently set for the specified callback + * object. + * @param obj The callback object. + */ + static void cancel_timer(mcl_timer_handler* obj); + + /** + * Cancels all timers that are currently set for the specified callback + * object and first argument. + * @param obj The callback object. + * @param arg1 The first callback argument. + */ + static void cancel_timer(mcl_timer_handler* obj, INT32 arg1); + +#if 0 + /** + * Cancels all timers that are currently set for the specified callback + * object and arguments. + * @param obj The callback object. + * @param arg1 The first callback argument. + * @param arg2 The second callback argument. + */ + static void cancel_timer(mcl_timer_handler* obj, INT32 arg1, INT32 arg2); +#endif + + /** + * Cancels all timers that are currently set for the specified callback + * object and arguments and return a status. + * @param obj The callback object. + * @param arg1 The first callback argument. + * @param arg2 The second callback argument. + * @return completion status: MCL_OK if at least one instance of + * the timer has been found and cancelled, MCL_ERROR otherwise + */ + static mcl_error_status cancel_timer(mcl_timer_handler* obj, + INT32 arg1, INT32 arg2); + + /** + * Naps for at least the specified number of milliseconds, usually a bit + * more. Callbacks will not be blocked while performing the nap. + * @param msec The number of milliseconds to nap for. + */ + static void nap(UINT32 msec); + + /** + * Yields the processor to any other thread waiting. + */ + static void yield_processor(); + + /** + * This method should be called before the application exits. This method + * will kill the timer thread, disabling all timers at the current time. + * Deleting all RMF objects and calling this method should allow the + * application to exit gracefully. Use this call with care. + */ + static void kill_thread(); + + +private: + + /** + * Allocates the timer arrays and starts the timer thread. + */ + static void start(); + + /** + * The timer thread run method for generating callbacks. + * @param arg The mcl_Timer object address cast as a void*. + */ + static void *run(void *arg); + + /** + * Convenience method for logging output. + * @param mn Method name. + * @param s Message string. + */ + static void log(char *mn, char *s); + + /** + * The initialization flag. + */ + static bool initialized; + + /** + * The timer array size. + */ + static INT32 array_size; + + /** + * The timer array scan size. + */ + static INT32 scan_size; + + /** + * The in use flag array. + */ + static bool *in_use; + + /** + * The expiration time array. + */ + static struct timeval *exp_time; + + /** + * The event handler callback object array. + */ + static mcl_timer_handler **object; + + /** + * The event handler callback argument1 array. + */ + static INT32 *argument1; + + /** + * The event handler callback argument2 array. + */ + static INT32 *argument2; + + /** + * The timer thread attributes. + */ + static mcl_THREAD_ATTR_TYPE timer_attr; + + /** + * The timer thread for callbacks. + */ + static mcl_THREAD_TYPE timer_thread; + + /** + * The timer mutex lock. + */ + static mcl_mutex_t timer_mutex; + + /** + * A flag to record if the timer mutex lock has been initialized. + */ + static bool timer_mutex_init; + +}; + + +//---------------------------------------------------------------------------- +// Inlines for all classes follow +//---------------------------------------------------------------------------- + +#endif // !MCL_TIMER_H diff --git a/src/norm/mcl_timer_handler.h b/src/norm/mcl_timer_handler.h new file mode 100644 index 0000000..9345232 --- /dev/null +++ b/src/norm/mcl_timer_handler.h @@ -0,0 +1,94 @@ +/* $Id: mcl_timer_handler.h,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * contains code derived from: + */ + +//============================================================================ +// Copyright (c) 1997-2001 TASC, Inc. +// Copyright (c) 1997-2001 University of Massachusetts at Amherst +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. All advertising materials mentioning features or use of this software +// must display the following acknowledgement: +// This product includes software developed by TASC, Inc. and the +// University of Massachusetts at Amherst. +// 4. The names of TASC, Inc. and the University of Massachusetts at Amherst +// may not be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS +// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +// DISCLAIMED. IN NO EVENT SHALL CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +// IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. +//---------------------------------------------------------------------------- +// + +#ifndef MCL_TIMER_HANDLER_H +#define MCL_TIMER_HANDLER_H + +/** + * Abstract class that provides a common method for timer callbacks. + * @version $Revision: 1.2 $ + * @author Mark Keaton + */ + +class mcl_timer_handler { + +public: + + //========================================================================== + /** + * The common timer callback method. + * @param arg1 The first callback argument. + * @param arg2 The second callback argument. + */ + virtual void timer_callback (INT32 arg1, INT32 arg2) = 0; + +protected: + +private: + +}; + + +//---------------------------------------------------------------------------- +// Inlines for all classes follow +//---------------------------------------------------------------------------- + +#endif // !MCL_TIMER_HANDLER_H diff --git a/src/norm/mcl_tx.cpp b/src/norm/mcl_tx.cpp new file mode 100644 index 0000000..c16bff0 --- /dev/null +++ b/src/norm/mcl_tx.cpp @@ -0,0 +1,249 @@ +/* $Id: mcl_tx.cpp,v 1.4 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +mcl_tx::mcl_tx () +{ + /* so that ADU seq effectively starts at MCL_ISS... */ + this->highest_adu_seq = (UINT32)(MCL_ISS - 1); + this->reuse_appli_tx_buffer = false; + this->adu_head = NULL; + this->next_norm_pkt_seq = 0; +} + + +mcl_tx::~mcl_tx () +{ + ASSERT(this->adu_head == NULL); +} + + +void +mcl_tx::free_all_adu (mcl_cb *const mclcb) +{ + mcl_adu *adu; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx::free_all_adu:\n")) + while ((adu = adu_head) != NULL) { + this->remove_adu(mclcb, adu); + delete adu; /* free the adu and all of its blocks/dus */ + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx::free_all_adu:\n")) +} + + +/** + * Set the transmission rate in bits per second (bps). + * The desired rate can be adjusted so that the is an integral + * number of packets per tick. + * @param desired_rate + * @return rate actually set + */ +float +mcl_tx::set_bps_tx_rate (mcl_cb *const mclcb, + const float desired_rate) +{ + // first of all, calculate the rounded packet per tick rate, but + // no less than 1 packet per tick +#ifdef SOLARIS + this->ppt_tx_rate = max(1, floor((double)desired_rate / (double)(mclcb->get_payload_size() * 8 * mcl_periodic_timer::get_frequency()))); +#else + this->ppt_tx_rate = max(1, floorf(desired_rate / (mclcb->get_payload_size() * 8 * mcl_periodic_timer::get_frequency()))); +#endif // OS + + // the other two rates derive from this ppt rate! + this->bps_tx_rate = this->ppt_tx_rate * mclcb->get_payload_size() * 8 * + mcl_periodic_timer::get_frequency(); + this->pps_tx_rate = this->ppt_tx_rate * + mcl_periodic_timer::get_frequency(); + TRACELVL(5, (mcl_stdout, + "mcl_tx::set_bps_tx_rate: desired=%.3f, ppt=%.3f, pps=%.3f, bps=%.3f, payload_sz=%d, freq=%.3f\n", + desired_rate, this->ppt_tx_rate, this->pps_tx_rate, + this->bps_tx_rate, mclcb->get_payload_size(), + mcl_periodic_timer::get_frequency())) + return (this->bps_tx_rate); +} + + +/** + * Set a pre-defined transmission profile. + * @return completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_tx::set_tx_profile (mcl_cb *const mclcb, + mcl_tx_profile prof) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_tx::set_tx_profile: %d\n", prof)) + switch (prof) { + case MCL_TX_PROFILE_LOW_RATE_INTERNET: + this->set_bps_tx_rate(mclcb, 32000); // 32 kbps + break; + case MCL_TX_PROFILE_MID_RATE_INTERNET: + this->set_bps_tx_rate(mclcb, 512000); // 512 kbps + break; + case MCL_TX_PROFILE_HIGH_SPEED_INTERNET: + this->set_bps_tx_rate(mclcb, 2000000); // 2 Mbps + break; + case MCL_TX_PROFILE_HIGH_SPEED_LAN: + this->set_bps_tx_rate(mclcb, 10000000); // 10 Mbps + break; + default: + PRINT_ERR((mcl_stderr, "<- mcl_tx::set_tx_profile: ERROR, invalid profil %d\n", prof)) + return MCL_ERROR; + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx::set_tx_profile: ok\n")) + return MCL_OK; +} + + +/** + * Try to send as much data as possible in a tx tick for this session. + */ +void +mcl_tx::try_to_send (mcl_cb *const mclcb) +{ + int du_nb; /* number of DUs to send */ + bool something_sent; /* flag: is there any DU to tx? */ + static bool no_new_obj_already_sent = false; /* send only once */ + + TRACELVL(5, (mcl_stdout, "-> mcl_tx::try_to_send:\n")) + if (!mclcb->is_a_sender() || mclcb->fsm.is_closed(mclcb)) { + TRACELVL(5, (mcl_stdout, "<- mcl_tx::try_to_send: ERROR, this mclcb cannot tx\n")) + return; + } + + something_sent= false; /* reset first */ + TRACELVL(5, (mcl_stdout, + " mcl_tx::try_to_send: ppt_rate=%.2f, %d DUs available\n", + this->get_pkt_per_tick_tx_rate(), + mclcb->tx_window.get_nb_of_available_du_to_tx())) + /* + * is there something to send? + */ + if ((du_nb = min((INT32)(this->get_pkt_per_tick_tx_rate()), + mclcb->tx_window.get_nb_of_available_du_to_tx())) > 0) { + /* yes */ + this->send_pkt(mclcb, du_nb); + something_sent = true; + } +#if 0 + // if (tl->tot_rem == 0 && + // mclcb->delivery_mode == DEL_MODE_ON_DEMAND) + if (tl->tot_rem == 0) { + /* + * get ready for a new tx cycle + * on that layer + */ + mcl_new_tx_cycle(mclcb, tl); + } +#endif + //if (something_sent == false && mclcb->fsm.no_new_adu(mclcb)) + if (something_sent == false && mclcb->fsm.finish_tx(mclcb)) { + if (no_new_obj_already_sent == false) { + /* + * first, send NO_NEW_OBJECT to inform receivers + * no new objects will be sent. + * do it only once (but with MCL_TX_ROBUSTNESS_FACTOR). + * + * performed here rather than immediately when moving to + * FINISH_TX state to avoid the problem of implicitely + * announced ADUs that occur if NO_NEW_OBJECT is + * received before a NEW_OBJECT. + */ + mclcb->tx_ctrl.send_no_new_object_pkt(mclcb); + /* + * then send a FLUSH for the last block + */ + mclcb->tx_ctrl.check_if_ctrl_pkt_must_be_sent(mclcb, + NULL, true); + no_new_obj_already_sent = true; + } + if (mclcb->tx_ctrl.is_there_pending_ctrl(mclcb) == false) { + /* + * really finished, no control operation pending, + * so stop everything and send the CLOSE pkt + */ + mclcb->fsm.update_tx_state(mclcb, TEVENT_ALL_DU_SENT); + mclcb->tx_ctrl.send_close_pkt(mclcb); + mclcb->fsm.update_tx_state(mclcb, TEVENT_CLOSE_SENT); + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx::try_to_send:\n")) +} + + +/* + * Send this number of DUs + */ +void +mcl_tx::send_pkt (mcl_cb *const mclcb, + INT32 du_nb) +{ + mcl_du *du = NULL; + norm_common_hdr_t *hdr; // norm header + INT32 hlen; // norm header length + INT32 rem; // remaining pkts waiting to be sent + + TRACELVL(5, (mcl_stdout, "-> mcl_tx::send_pkt: %d DUs\n", du_nb)) + ASSERT(du_nb > 0); + ASSERT(mclcb->tx_window.get_nb_of_available_du_to_tx() >= du_nb); + + for (rem = du_nb; rem > 0; rem--) { + /* retrieve the next du that should be sent */ + du = mclcb->tx_window.get_next_du_to_tx(mclcb); + ASSERT(du); + /* create the NORM packet */ + if ((hlen = mclcb->norm_pkt_mgmt.create_data_hdr(mclcb, du, &hdr)) <= 0) { + PRINT_ERR((mcl_stderr, "mcl_tx::send_pkt: norm_pkt_mgmt.create_data_hdr() failed\n")) + ASSERT(0); // in debug mode, stop immediately... + return; + } + /* then send the packet */ + mclcb->ses_channel.send_pkt(mclcb, hdr, hlen, du); + PRINT_LVL(1, (mcl_stdout, "\t%s %d/%d/%d\n", + (du->is_fec ? "fec" : "data"), + du->block->adu->get_seq(), du->block->seq, + du->seq)) +#if 0 + {static UINT32 pp_adu = 66666666; + static UINT32 pp_blk = 66666666; + static UINT32 pp_du = 66666666; + + if (du->block->adu->get_seq() == pp_adu && + du->block->seq == pp_blk && + du->seq == pp_du) { + printf("mcl_tx::send_pkt: ERROR, pkt sent just before!\n"); + mcl_exit(-1); + } + pp_adu = du->block->adu->get_seq(); + pp_blk = du->block->seq; + pp_du = du->seq; + } +#endif + /* see if any control packet must be issued or not */ + mclcb->tx_ctrl.check_if_ctrl_pkt_must_be_sent(mclcb, du, false); + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx::send_pkt:\n")) +} + + diff --git a/src/norm/mcl_tx.h b/src/norm/mcl_tx.h new file mode 100644 index 0000000..4884f4f --- /dev/null +++ b/src/norm/mcl_tx.h @@ -0,0 +1,301 @@ +/* $Id: mcl_tx.h,v 1.4 2004/05/26 07:36:04 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_TX_H +#define MCL_TX_H + +#include "mcl_lib_api_norm.h" + +/** + * This Class controls many aspects related to transmissions. + */ +class mcl_tx { + +public: + /****** Public Members ************************************************/ + mcl_tx (); + ~mcl_tx (); + + /** + * Return the adu sequence number to use for a newly submitted adu + * AND INCREMENT the counter. + * @return returns the adu sequence number to use + */ + UINT32 get_seq_for_new_adu (); + + /** + * Return the highest adu seq number ever submitted by the sending app. + * @return highest adu seq number submitted + */ + UINT32 get_highest_submitted_adu_seq () const; + + /** + * Informs there won't be any more ADU. + * This function is called as soon as the sending application + * issues a mcl_close(). + */ + void set_no_new_adu (mcl_cb *const mclcb); + + /** + * Insert the adu in the tx adu list. + * @param mclcb + * @param adu + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status insert_adu (mcl_cb *const mclcb, + mcl_adu *const adu); + /** + * Remove the adu from the tx adu list. + * @param mclcb + * @param adu + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status remove_adu (mcl_cb *const mclcb, + mcl_adu *const adu); + + /** + * Get the first adu of the tx adu list. + */ + mcl_adu *get_first_adu (mcl_cb *const mclcb); + + /** + * Get the last adu of the tx adu list. + */ + mcl_adu *get_last_adu (mcl_cb *const mclcb); + + /** + * Free all the adus of the tx adu list. + * This function is only called at session close/abort. + */ + void free_all_adu (mcl_cb *const mclcb); + + /** + * Find an ADU in the receiving window with its sequence number. + * @param mclcb + * @param seq ADU seq number + * @return returns a pointer to the adu if found, NULL otherwise + */ + mcl_adu *find_adu (mcl_cb *const mclcb, + UINT32 idf_adu); + + /** + * Determine if application buffer can be reused by MCL or not. + * @param val boolean + */ + void set_reuse_appli_buf_bool (bool val); + + /** + * True if application buffer can be reused by MCL. + * @return boolean + */ + bool can_reuse_appli_buf () const; + + /** + * Get the transmission rate in bits per second (bps). + * @return current transmission rate + */ + float get_bps_tx_rate () const; + + /** + * Get the transmission rate in packets per second (pps). + * @return current transmission rate + */ + float get_pkt_per_sec_tx_rate () const; + + /** + * Get the transmission rate in packets per tick (ppt). + * @return current transmission rate + */ + float get_pkt_per_tick_tx_rate () const; + + /** + * Set the transmission rate in bits per second (bps). + * The desired rate can be adjusted so that the is an integral + * number of packets per tick. + * @param desired_rate desired rate in bits per second + * @return rate actually set + */ + float set_bps_tx_rate (mcl_cb *const mclcb, + const float desired_rate); + + /** + * Set a pre-defined transmission profile. + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status set_tx_profile (mcl_cb *const mclcb, + mcl_tx_profile prof); + + /** + * Try to send as much data as possible in a tx tick for this session. + * This is the general sending function. + * @param mclcb + */ + void try_to_send (mcl_cb *mclcb); + + /** + * Return the NORM sequence number of the following packet to send. + * The internal counter is automatically incremented by this call. + * The internal counter (a UINT16) cycles regularly, this is normal! + */ + UINT16 get_next_norm_pkt_seq (); + + + /****** Public Attributes *********************************************/ + + + +private: + /****** Private Members ***********************************************/ + /** + * Send this number of DUs for this session. + * @param mclcb + * @param du_nb Number of DUs to send + */ + void send_pkt (mcl_cb *const mclcb, + INT32 du_nb); + + /****** Private Attributes ********************************************/ + UINT32 highest_adu_seq;// highest seq nb of ADUs submit. so far + bool reuse_appli_tx_buffer; + mcl_adu *adu_head; // head of ADU doubly linked list + + /** Transmission rate in bits per second (bps) */ + float bps_tx_rate; + /** Transmission rate in packets per second (pps) */ + float pps_tx_rate; + /** Transmission rate in packets per tick of the periodic timer (ppt). + * It must be an integer */ + float ppt_tx_rate; + + /** + * Counter incremented each time a NORM packet is sent, no matter + * its type. + * Used to discover packet losses in a continuous flow. + */ + UINT16 next_norm_pkt_seq; + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + + +inline UINT32 +mcl_tx::get_seq_for_new_adu () +{ + this->highest_adu_seq++; + return this->highest_adu_seq; +} + +inline UINT32 +mcl_tx::get_highest_submitted_adu_seq () const +{ + return this->highest_adu_seq; +} + +inline void +mcl_tx::set_no_new_adu (mcl_cb *const mclcb) +{ + //if (mclcb->fsm.no_new_adu(mclcb) == false) + // exit(-1); + //ASSERT(mclcb->fsm.no_new_adu(mclcb)); +} + +inline mcl_error_status +mcl_tx::insert_adu (mcl_cb *const mclcb, + mcl_adu *const adu) +{ + //ASSERT(mclcb->fsm.no_new_adu(mclcb) == false); + adu->insert_in_list(mclcb, &(this->adu_head)); + return MCL_OK; +} + +inline mcl_error_status +mcl_tx::remove_adu (mcl_cb *const mclcb, + mcl_adu *const adu) +{ + adu->remove_from_list(mclcb, &(this->adu_head)); + return MCL_OK; +} + + +inline mcl_adu * +mcl_tx::get_first_adu (mcl_cb *const mclcb) +{ + return this->adu_head; +} + +inline mcl_adu * +mcl_tx::get_last_adu (mcl_cb *const mclcb) +{ + return ((this->adu_head != NULL) ? this->adu_head->get_prev() : NULL); +} + +inline mcl_adu * +mcl_tx::find_adu (mcl_cb *const mclcb, + UINT32 idf_adu) +{ + return this->adu_head->find_in_list(mclcb, this->adu_head, idf_adu); +} + +inline void +mcl_tx::set_reuse_appli_buf_bool (bool val) +{ + this->reuse_appli_tx_buffer = val; +} + +inline bool +mcl_tx::can_reuse_appli_buf () const +{ + return this->reuse_appli_tx_buffer; +} + +inline float +mcl_tx::get_bps_tx_rate () const +{ + return this->bps_tx_rate; +} + +inline float +mcl_tx::get_pkt_per_sec_tx_rate () const +{ + return this->pps_tx_rate; +} + +inline float +mcl_tx::get_pkt_per_tick_tx_rate () const +{ + return this->ppt_tx_rate; +} + +inline UINT16 +mcl_tx::get_next_norm_pkt_seq () +{ + UINT16 s = next_norm_pkt_seq; + next_norm_pkt_seq++; + return s; +} + + +#endif // !MCL_TX_H + diff --git a/src/norm/mcl_tx_buffer_mgmt.h b/src/norm/mcl_tx_buffer_mgmt.h new file mode 100644 index 0000000..51f4979 --- /dev/null +++ b/src/norm/mcl_tx_buffer_mgmt.h @@ -0,0 +1,51 @@ +/* $Id: mcl_tx_buffer_mgmt.h,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_TX_BUFFER_MGMT_H +#define MCL_TX_BUFFER_MGMT_H + +typedef struct { + ulong cur_buf_space; + ulong max_buf_space; +} tx_buffer_stats_t; + + +// main class +class tx_buffer_mgmt { +public: + void tx_buffer_mgmt (); + void ~tx_buffer_mgmt (); + // returns < 0 if error, pointer to new buffer if ok + char *alloc (int size); + // returns < 0 if error, 0 if ok + int free (char *buf); + // statistics + ulong get_cur_buf_space_stats (void); + ulong get_max_buf_space_stats (void); + +private: + int k; + int n; + mcl_thread_t fec_encoding_thread; + tx_buffer_stats_t stats; +} + +#endif // MCL_TX_BUFFER_MGMT_H diff --git a/src/norm/mcl_tx_ctrl.cpp b/src/norm/mcl_tx_ctrl.cpp new file mode 100644 index 0000000..9045a51 --- /dev/null +++ b/src/norm/mcl_tx_ctrl.cpp @@ -0,0 +1,1047 @@ +/* $Id: mcl_tx_ctrl.cpp,v 1.3 2004/02/18 07:56:18 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * Default constructor. + */ +mcl_tx_ctrl:: mcl_tx_ctrl() +{ + this->blk_of_last_du = NULL; + this->FLUSH_DONE_tevent_head = NULL; + this->RETX_DONE_tevent_head = NULL; +} + + +/** + * See if any control packet must be sent or not, and send it if + * necessary. + * @param mclcb + * @param du DU that has just been sent + * @param end_session boolean true after the transmission of + * the last DU of the last block of a session. + * Used to trigger the tx of a FLUSH + */ +void +mcl_tx_ctrl::check_if_ctrl_pkt_must_be_sent (mcl_cb *const mclcb, + mcl_du *du, + bool end_session) +{ + TRACELVL(5, (mcl_stdout, + "-> mcl_tx_ctrl::check_if_ctrl_pkt_must_be_sent:\n")) + if (end_session == false) { + /* + * normal case: a DU has just been sent, see if we need + * to send a FLUSH. + */ + ASSERT(du); + if (du->is_fec) { + /* ignore */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::check_if_ctrl_pkt_must_be_sent: ignored (FEC DU)\n")) + return; + } + if (du->block == this->blk_of_last_du || this->blk_of_last_du == NULL) { + /* do nothing... */ + this->blk_of_last_du = du->block; + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::check_if_ctrl_pkt_must_be_sent: nothing done\n")) + return; + } + } + /* + * we need to send a FLUSH. + * So create and send a FLUSH packet for the previous block. + */ + this->send_flush_and_register_tevent(mclcb, this->blk_of_last_du); + /* + * finish now + */ + if (end_session) { + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::check_if_ctrl_pkt_must_be_sent: end of session, FLUSH sent\n")) + return; + } else if (this->blk_of_last_du->adu == du->block->adu) { + /* + * same ADU, so end of processing + */ + this->blk_of_last_du = du->block; + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::check_if_ctrl_pkt_must_be_sent: moved to new block, FLUSH sent\n")) + return; + } else { + /* + * transmission for a new ADU + * mark the previous ADU as in its final step... + */ + this->blk_of_last_du->adu->set_tx_status(ADU_TSTATUS_FINISH_TX); + this->blk_of_last_du = du->block; + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::check_if_ctrl_pkt_must_be_sent: moved to new ADU\n")) + return; + } +} + + +/** + * Send NORM_CMD(FLUSH) packet(s) and register a FLUSH_DONE + * timer event. + * @param mclcb + * @param blk block for which we need to send a FLUSH + */ +void +mcl_tx_ctrl::send_flush_and_register_tevent (mcl_cb *const mclcb, + mcl_block *blk) +{ + mcl_tx_ctrl_FLUSH_DONE_tevent *te, // FLUSH timer event + *prev_te; // previous timer event + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl::send_flush_and_register_tevent:\n")) + /* + * create and send a FLUSH packet for this block (pick + * up any of its du, e.g. the first of list) + */ + this->send_cmd_pkt(mclcb, NORM_CMD_FLUSH, blk->get_du_head()); + /* + * create a new FLUSH_DONE timer event + */ + te = new mcl_tx_ctrl_FLUSH_DONE_tevent(blk->adu->get_seq(), blk->seq); + /* + * check if a FLUSH_DONE tevent already exists, and if yes + * delete the previous event and replace if with the new one. + */ + prev_te = te->find_in_list(mclcb, &(this->FLUSH_DONE_tevent_head)); + if (prev_te) { + /* already present, so drop the previous one */ + TRACELVL(5, (mcl_stdout, + " mcl_tx_ctrl::send_flush_and_register_tevent: replace old FLUSH_DONE tevent by the new one\n")) + /* remove the FLUSH_DONE from list */ + if (prev_te->remove_from_list(mclcb, + &(this->FLUSH_DONE_tevent_head)) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::check_if_ctrl_pkt_must_be_sent: remove_from_list() failed\n")) + mcl_exit(-1); + } + /* and cancel the timer */ + if (mclcb->timer.cancel_timer((mcl_timer_handler *)this, + (INT32)mclcb, (INT32)prev_te) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::check_if_ctrl_pkt_must_be_sent: cancel_timer() failed for FLUSH_DONE event, blk %d/%d\n", + blk->adu->get_seq(), blk->seq)) + // do not exit but do not delete the tevent! + } else { + /* now we can delete the tevent */ + delete prev_te; + } + } + /* + * insert it in the tevent list and set a timer for + * a delayed FLUSH_DONE management... + */ + te->insert_in_list(mclcb, &(this->FLUSH_DONE_tevent_head)); + mclcb->timer.set_timer(FLUSH_DONE_TIMEOUT, (mcl_timer_handler *)this, + (INT32)mclcb, (INT32)te); + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl::send_flush_and_register_tevent:\n")) +} + + +/** + * Send NORM_CMD(FLUSH) packet(s). + * @param mclcb + * @param blk block for which we need to send a FLUSH + */ +void +mcl_tx_ctrl::send_flush_pkt (mcl_cb *const mclcb, + mcl_block *blk) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl::send_flush_pkt:\n")) + /* + * create and send a FLUSH packet for the previous block (pick + * up any of its du, e.g. the first of list) + */ + this->send_cmd_pkt(mclcb, NORM_CMD_FLUSH, blk->get_du_head()); + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl::flush_pkt:\n")) +} + + +/** + * Send NORM_CMD(NO_NEW_OBJECT) packet(s). + */ +void +mcl_tx_ctrl::send_no_new_object_pkt (mcl_cb *const mclcb) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl::send_no_new_object_pkt:\n")) + this->send_cmd_pkt(mclcb, NORM_CMD_NO_NEW_OBJECT, NULL); + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl::send_no_new_object_pkt:\n")) +} + + +/** + * Send NORM_CMD(CLOSE) packet(s). + */ +void +mcl_tx_ctrl::send_close_pkt (mcl_cb *const mclcb) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl::send_close_pkt:\n")) + this->send_cmd_pkt(mclcb, NORM_CMD_CLOSE, NULL); + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl::send_close_pkt:\n")) +} + + +/** + * Send NORM_CMD(any flavor) packet(s). + * Sends MCL_TX_ROBUSTNESS_FACTOR copies of the packet. + * Used by send_no_new_object_pkt() and send_close_pkt() functions. + * @param mclcb + * @param flavor flavor of the command packet + * @param du only required for NORM_CMD_FLUSH + */ +void +mcl_tx_ctrl::send_cmd_pkt (mcl_cb *const mclcb, + norm_cmd_flavor flavor, + mcl_du *du) +{ + norm_common_hdr_t *hdr; // norm header + INT32 hlen = 0; // norm header length + INT32 robustness; // number of tx + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl::send_cmd_pkt:\n")) + /* create the NORM packet */ + switch (flavor) { + case NORM_CMD_NO_NEW_OBJECT: + if ((hlen = mclcb->norm_pkt_mgmt.create_cmd_no_new_object_hdr + (mclcb, &hdr)) <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::send_cmd_pkt: norm_pkt_mgmt.create_cmd_no_new_object_hdr() failed\n")) + ASSERT(0); // in debug mode, stop immediately... + return; + } + break; + + case NORM_CMD_CLOSE: + if ((hlen = mclcb->norm_pkt_mgmt.create_cmd_close_hdr + (mclcb, &hdr)) <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::send_cmd_pkt: norm_pkt_mgmt.create_cmd_close_hdr() failed\n")) + ASSERT(0); // in debug mode, stop immediately... + return; + } + break; + + case NORM_CMD_FLUSH: + ASSERT(du); + if ((hlen = mclcb->norm_pkt_mgmt.create_cmd_flush_hdr + (mclcb, &hdr, du)) <= 0) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::send_cmd_pkt: norm_pkt_mgmt.create_cmd_flush_hdr() failed\n")) + ASSERT(0); // in debug mode, stop immediately... + return; + } + break; + + default: + mcl_exit(-1); + } + + /* then send the packet */ + switch (flavor) { + case NORM_CMD_NO_NEW_OBJECT: + case NORM_CMD_CLOSE: + for (robustness = MCL_TX_ROBUSTNESS_FACTOR; robustness > 0; + robustness--) { + mclcb->ses_channel.send_pkt(mclcb, hdr, hlen, NULL); + if (mclcb->get_verbosity() >= 1) { + switch (flavor) { + case NORM_CMD_NO_NEW_OBJECT: + PRINT_OUT((mcl_stdout, "\tNO_NEW_OBJECT\n")) + break; + case NORM_CMD_CLOSE: + PRINT_OUT((mcl_stdout, "\tCLOSE\n")) + break; + default: + mcl_exit(-1); + } + } + } + break; + + case NORM_CMD_FLUSH: + for (robustness = MCL_TX_CMD_FLUSH_ROBUSTNESS_FACTOR; + robustness > 0; robustness--) { + mclcb->ses_channel.send_pkt(mclcb, hdr, hlen, NULL); + PRINT_LVL(1, (mcl_stdout,"\tFLUSH sent for blk %d/%d\n", + du->block->adu->get_seq(), du->seq)) + } + break; + + default: + mcl_exit(-1); + } + + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl::send_cmd_pkt:\n")) +} + + +/** + * Process an incoming NORM_NACK packet. + * @param mclcb + * @param pkt pointer to packet + * @param saddr source address for this packet + * @param chdr_infos pointer to the common_infos struct + */ +mcl_error_status +mcl_tx_ctrl::process_nack_pkt (mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_addr *saddr, + mcl_common_hdr_infos_t *chdr_infos) +{ + mcl_data_hdr_infos_t dhdr_infos; // infos of NACK hdr, in host format + norm_nack_content_hdr_t *nc; // NACK content hdr, in host format + mcl_adu *adu; // adu concerned by the NACK + mcl_block *blk; // block concerned by NACK if applicable + INT32 fec_required; // # fec req. for repair, i.e. + // asked by the receiver + INT32 fec_avail; // # fec already available but + // not yet sent + INT32 add_possible_fec;// # fec that can still be + // created + INT32 fec_nb; // # fec packets actually created and + // that will be sent + mcl_tx_ctrl_RETX_DONE_tevent *te; // timer event + mcl_tx_ctrl_FLUSH_DONE_tevent *tmp_flush_te; // temporary tevent + mcl_tx_ctrl_FLUSH_DONE_tevent *prev_flush_te; // FLUSH timer event + // that triggered this NACK + + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl::process_nack_pkt:\n")) + /* + * process the NORM_NACK header + */ + memset(&dhdr_infos, 0, sizeof(mcl_data_hdr_infos_t)); + if (mclcb->norm_pkt_mgmt.parse_nack_hdr(mclcb, pkt, &dhdr_infos) + == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: ERROR, bad NORM header\n")) + goto bad_hdr; + } + /* + * process each norm_nack_content_hdr_t block... + */ + while ((nc = mclcb->norm_pkt_mgmt.get_next_nack_content_block(mclcb, pkt)) != NULL) { + /* from now on, the various nc fields are in host format and + * can be used directly... */ + switch (nc->form) { + case NORM_NACK_ERASURES: + break; + default: + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: ERROR, unknown nack_content_hdr form %d\n", nc->form)) +#ifdef DEBUG + mcl_exit(-1); +#else + goto bad_hdr; +#endif + } + + switch (nc->flags) { + case NORM_NACK_BLOCK: + break; + default: + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: ERROR, unknown nack_content_hdr flags %d\n", nc->flags)) +#ifdef DEBUG + mcl_exit(-1); +#else + goto bad_hdr; +#endif + } + /* find the adu first */ + if (!(adu = mclcb->tx.find_adu(mclcb, nc->obj_transp_id))) { + /* + * for some reason this ADU is not in tx window, + * probably because it has already been free'ed... + */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::process_nack_pkt: WARNING, adu %d not found in tx window\n", + nc->obj_transp_id)) + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: ERROR, TODO\n")) + goto bad_hdr; + } + /* then find the block */ + if (!(blk = adu->find_block(mclcb, nc->fec_block_nb))) { + /* + * for some reason this block is not in tx window, + * probably because it has already been free'ed, or + * because of an error at the receiver. + */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::process_nack_pkt: WARNING, block %d not found in tx window\n", + nc->fec_block_nb)) + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: ERROR, TODO\n")) + goto bad_hdr; + } + /* + * create a new tevent + */ + te = new mcl_tx_ctrl_RETX_DONE_tevent(adu->get_seq(), blk->seq); + /* + * avoid considering a NACK for a block which is currently + * being repaired, i.e. for which already exists a RETX_DONE + * tevent. + */ + if (te->find_in_list(mclcb, &(this->RETX_DONE_tevent_head))) { + /* NACK already processed, ignore */ + TRACELVL(5, (mcl_stdout, + " mcl_tx_ctrl::process_nack_pkt: NACK ignored (under repair)\n")) + delete te; + return MCL_OK; + } + /* + * now schedule enough additional FEC packets. + * needs to take into account the receiver needs, the + * available fec that has not yet been sent, and the + * remaining fec packets that can still be created... + */ + fec_required = nc->fec_symbol_id_or_erasure_count + 2; + // two extra packets for security, in case of losses + fec_avail = mclcb->fec.get_nb_fresh_fec_pkts(mclcb, blk); + add_possible_fec = mclcb->fec.get_rem_nb_fec_pkts_to_create(mclcb, blk); + if (fec_required <= fec_avail) { + /* + * enough available FEC, no need to create more. + * schedule transmission of available fec packets + */ + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: ERROR, TODO, sched avail fec pkts\n")) + // TODO + mcl_exit(-1); + } else if (fec_required <= fec_avail + add_possible_fec) { + /* we need to create additional fec and it is possible*/ + /* + * create additional fec pkts first. + * these FEC packets will automatically be scheduled + * once created + */ + fec_nb = mclcb->fec.encode(mclcb, blk, + fec_required - fec_avail); + if (fec_nb < 0) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: ERROR, FEC encoding failed\n")) + goto encoding_error; + } +#ifdef DEBUG + if (fec_nb < fec_required - fec_avail) { + /* + * this is not serious! It can happen because + * of pending FEC creation requests. + */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::process_nack_pkt: WARNING, %d fec produced instead of %d\n", + fec_nb, fec_required - fec_avail)) + } +#endif /* DEBUG */ + /* schedule transmission of available fec packets */ + if (fec_avail > 0) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: ERROR, TODO, sched avail fec pkts 2\n")) + // TODO + mcl_exit(-1); + } + } else { + /* + * Retransmit everything, data plus available fec. + * + * The idea is to try to retransmit all FEC DUs + * available, even if already tx before. If this + * is possible, no data pkts will be retransmitted. + * If not sufficient, then the idea is to transmit + * all data DUs, without FEC DUs. + */ + INT32 du_to_tx; // nb of data DUs to tx + INT32 fec_du_to_tx; // nb of FEC DUs to tx + + if (blk->get_fec_du_nb_in_list() >= fec_required) { + /* tx only FEC */ + du_to_tx = 0; + fec_du_to_tx = fec_required; + } else { + du_to_tx = blk->du_nb; + fec_du_to_tx = 0; + } + if (mclcb->tx_window.reschedule_tx_for_block(mclcb, blk, + du_to_tx, fec_du_to_tx) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, "mcl_tx_ctrl::process_nack_pkt: ERROR, reschedule_tx_for_block() failed\n")) + goto encoding_error; + } + } + /* + * insert it in the tevent list and set a timer for + * a delayed FLUSH transmission... + */ + te->insert_in_list(mclcb, &(this->RETX_DONE_tevent_head)); + mclcb->timer.set_timer(RETX_DONE_TIMEOUT, + (mcl_timer_handler *)this, + (INT32)mclcb, (INT32)te); + /* + * remove the corresponding FLUSH_DONE tevent for the + * same block which triggered this NACK (there should be one!) + */ + tmp_flush_te = new mcl_tx_ctrl_FLUSH_DONE_tevent( + blk->adu->get_seq(), blk->seq); + prev_flush_te = tmp_flush_te->find_in_list(mclcb, + &(this->FLUSH_DONE_tevent_head)); + if (prev_flush_te) { + /* remove the FLUSH_DONE from list */ + if (prev_flush_te->remove_from_list(mclcb, + &(this->FLUSH_DONE_tevent_head)) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: remove_from_list() failed\n")) + mcl_exit(-1); + } + /* and cancel the timer */ + if (mclcb->timer.cancel_timer((mcl_timer_handler *)this, + (INT32)mclcb, (INT32)prev_flush_te) == MCL_ERROR) { + PRINT_ERR((mcl_stderr, + "mcl_tx_ctrl::process_nack_pkt: cancel_timer() failed for FLUSH_DONE event, blk %d/%d\n", + adu->get_seq(), blk->seq)) + // do not exit but do not delete the tevent! + //mcl_exit(-1); + } else { + /* now we can delete the tevent */ + delete prev_flush_te; + } + } + delete tmp_flush_te; + + PRINT_LVL(1, (mcl_stdout, + "\tNACK recvd for %d/%d, missing %d\n", + adu->get_seq(), blk->seq, fec_required)) + } + delete pkt; // free the now useless packet buffer + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl::process_nack_pkt:\n")) + return MCL_OK; + + +bad_hdr: + mclcb->stats.bad_hdr++; + mclcb->stats.errors++; + delete pkt; // free the now useless packet buffer + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::process_nack_pkt: ERROR, bad hdr\n")) + return MCL_ERROR; + +encoding_error: + mclcb->stats.errors++; + delete pkt; // free the now useless packet buffer + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl::process_nack_pkt: ERROR\n")) + return MCL_ERROR; +} + + +/** + * timer callback method. + * @param arg1 mclcb + * @param arg2 pointer to an tx_ctrl_timer_event_t struct + */ +void +mcl_tx_ctrl::timer_callback (INT32 arg1, + INT32 arg2) +{ + mcl_cb *mclcb; // session of this event + mcl_tx_ctrl_tevent *tevent;// timer event + + /* + * WARNING, there is a risk that the mclcb context has disappeared + * when this function is called. Should check the validity of the + * mclcb arg quickly... + */ + mclcb = (mcl_cb*)arg1; + ASSERT(mclcb); + mclcb->lock(); + tevent = (mcl_tx_ctrl_tevent *)arg2; + ASSERT(tevent); + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl::timer_callback: %s\n", + tevent->get_type_string())) + /* + * Timer processing... + */ + switch (tevent->type) { + case TX_CTRL_TEVENT_FLUSH_DONE: { + mcl_tx_ctrl_FLUSH_DONE_tevent *te = (mcl_tx_ctrl_FLUSH_DONE_tevent*)tevent; + /* + * check if the tevent is still in list. If not it means + * that it has been removed after a NACK reception + */ + if ((te->find_in_list(mclcb, + &(mclcb->tx_ctrl.FLUSH_DONE_tevent_head))) + == NULL) { + /* so ignore... */ + TRACELVL(5, (mcl_stdout, + " mcl_tx_ctrl::timer_callback: FLUSH_DONE already removed\n")) + delete te; + break; + } + ASSERT(te == te->find_in_list(mclcb, &(mclcb->tx_ctrl.FLUSH_DONE_tevent_head))); + /* + * and then perform tevent processing + */ + if (te->process(mclcb) == true) { + /* + * processing of this FLUSH_DONE event is over... + * free and remove from list. + */ + te->remove_from_list(mclcb, &(mclcb->tx_ctrl.FLUSH_DONE_tevent_head)); + delete te; + } /* else do nothing */ + break; + } + + case TX_CTRL_TEVENT_RETX_DONE: { + mcl_tx_ctrl_RETX_DONE_tevent *te = (mcl_tx_ctrl_RETX_DONE_tevent*)tevent; + /* remove the tevent from the list first */ + if ((te->find_in_list(mclcb, + &(mclcb->tx_ctrl.RETX_DONE_tevent_head))) + != NULL) { + ASSERT(te == te->find_in_list(mclcb, + &(mclcb->tx_ctrl.RETX_DONE_tevent_head))); + te->remove_from_list(mclcb, + &(mclcb->tx_ctrl.RETX_DONE_tevent_head)); + } + /* and then perform tevent processing */ + te->process(mclcb); + delete te; + break; + } + + default: + ASSERT(0); + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl::timer_callback:\n")) + mclcb->unlock(); + return; + +#if 0 +bad: + TRACELVL(5, (mcl_stdout, "<- mcl_rx_ctrl::timer_callback: ERROR\n")) + mclcb->unlock(); + return; +#endif +} + + +/** + * See if there is one or more registered pending control + * operations (i.e. tevent). + * @param mclcb + * @return true if there is one or more pending ctrl operation + */ +bool +mcl_tx_ctrl::is_there_pending_ctrl (mcl_cb *const mclcb) +{ + if (this->RETX_DONE_tevent_head != NULL || + this->FLUSH_DONE_tevent_head != NULL) + return true; + else + return false; +} + + +/****** mcl_tx_ctrl_tevent base class *****************************************/ + +#if 0 +/** + * Default constructor + */ +mcl_tx_ctrl_tevent::mcl_tx_ctrl_tevent (mcl_tx_ctrl_tevent_types t) +{ + this->type = t; +} +#endif + + +/** + * Default destructor + */ +mcl_tx_ctrl_tevent::~mcl_tx_ctrl_tevent () +{ +} + + +#ifdef DEBUG +/** + * Return the tevent type as a static string. + */ +char * +mcl_tx_ctrl_tevent::get_type_string () const +{ + // WARNING: must be compliant with mcl_tx_ctrl_tevent_types definition! + static char *type_strings[] = { + "TX_CTRL_TEVENT_INVALID", + "TX_CTRL_TEVENT_FLUSH_DONE", + "TX_CTRL_TEVENT_RETX_DONE" + }; + + return type_strings[this->type]; +} +#endif // DEBUG + + +/** + * Insert a tevent in an unordered list. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ +mcl_error_status +mcl_tx_ctrl_tevent::insert_in_list (mcl_cb *const mclcb, + mcl_tx_ctrl_tevent **head) +{ + ASSERT(head); + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl_tevent::insert_in_list:\n")) + if (!(*head)) { + /* + * first tevent in list + */ + *head = this; + this->next = this->prev = this; + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl_tevent::insert_in_list: ok, inserted in empty list\n")) + } else { + /* + * insert in list tail. + */ + this->next = *head; + this->prev = (*head)->prev; + (*head)->prev->next = this; + (*head)->prev = this; + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl_tevent::insert_in_list:\n")) + } + return MCL_OK; +} + + +/** + * Remove a tevent from an unordered list. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ +mcl_error_status +mcl_tx_ctrl_tevent::remove_from_list (mcl_cb *const mclcb, + mcl_tx_ctrl_tevent **head) +{ + mcl_tx_ctrl_tevent *p, *n; // temp prev and next pointers + + ASSERT(head); + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl_tevent::remove_from_list:\n")) + ASSERT(*head); + p = this->prev; + n = this->next; + if (p == this) { /* only one tevent in list */ + ASSERT(n == this); + *head = NULL; /* list is now empty */ + } else { + p->next = n; + n->prev = p; + if (*head == this) { + *head = n; /* adu was the first in list */ + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl_tevent::remove_from_list:\n")) + return MCL_OK; +} + + +/****** FLUSH_DONE class ******************************************************/ + +/** + * Default constructor. + */ +mcl_tx_ctrl_FLUSH_DONE_tevent::mcl_tx_ctrl_FLUSH_DONE_tevent + (UINT32 adu_idf, + UINT32 block_idf) +{ + this->type = TX_CTRL_TEVENT_FLUSH_DONE; + this->adu_id = adu_idf; + this->block_id = block_idf; + this->repeat_count = UNANSWERED_FLUSH_REPEAT_COUNT; +} + + +/** + * Default destructor. + */ +mcl_tx_ctrl_FLUSH_DONE_tevent::~mcl_tx_ctrl_FLUSH_DONE_tevent () +{ +} + + +/** + * Find a FLUSH_DONE_tevent in an unordered list with a type-dependant criteria. + * @param mclcb + * @param head pointer to the list head pointer + * @return returns a pointer to the tevent if found, NULL otherwise + */ +mcl_tx_ctrl_FLUSH_DONE_tevent * +mcl_tx_ctrl_FLUSH_DONE_tevent::find_in_list (mcl_cb *const mclcb, + mcl_tx_ctrl_tevent **head) +{ + mcl_tx_ctrl_FLUSH_DONE_tevent *tevent; + mcl_tx_ctrl_FLUSH_DONE_tevent *nhead; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl_tevent::find_in_list:\n")) + ASSERT(head); + if (!(nhead = (mcl_tx_ctrl_FLUSH_DONE_tevent*)(*head))) { + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_tevent::find_in_list: empty list\n")) + return NULL; + } + /* + * start from the list tail + */ + tevent = (mcl_tx_ctrl_FLUSH_DONE_tevent*)(nhead->prev); + while (1) { + ASSERT(tevent); + if ((tevent->adu_id == this->adu_id) && + (tevent->block_id == this->block_id)) { + /* found */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_tevent::find_in_list: found\n")) + return tevent; + } + if (tevent == nhead) { + /* we have cycled and tevent is not in list */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_tevent::find_in_list: not found\n")) + return NULL; + } + tevent = (mcl_tx_ctrl_FLUSH_DONE_tevent*)tevent->prev; + } +} + + +/** + * Perform FLUSH_DONE_tevent specific processing. + * @return true if tevent is completed and should be free'ed and + * removed from list, false if it has been re-scheduled. + */ +bool +mcl_tx_ctrl_FLUSH_DONE_tevent::process (mcl_cb *const mclcb) +{ + mcl_adu *adu; + mcl_block *blk; + bool free_adu; // true if ADU can be free'ed + mcl_block *blk_tmp; + UINT32 rem; + + TRACELVL(5, (mcl_stdout, + "-> mcl_tx_ctrl_FLUSH_DONE_tevent::process:\n")) + /* find the adu first */ + if (!(adu = mclcb->tx.find_adu(mclcb, this->adu_id))) { + /* + * for some reason this ADU is not in tx window... give-up! + */ + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl_FLUSH_DONE_tevent::process: WARNING, adu not found in tx window\n")) + goto error; + } + /* then find the block */ + if (!(blk = adu->find_block(mclcb, this->block_id))) { + /* + * for some reason this block is not in tx window... give-up! + */ + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl_FLUSH_DONE_tevent::process: WARNING, block not found in tx window\n")) + goto error; + } + /* + * should it be the last FLUSH? + */ + if (this->repeat_count > 0) { + /* + * for improved robustness send the FLUSH once again, + * just in case the previous one(s) was lost, and + * schedule a new callback... + */ + this->repeat_count--; + mclcb->tx_ctrl.send_flush_pkt(mclcb, blk); + mclcb->timer.set_timer(FLUSH_DONE_TIMEOUT, + (mcl_timer_handler *)&(mclcb->tx_ctrl), + (INT32)mclcb, (INT32)this); + /* + * done... do not delete the tevent object! + */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_FLUSH_DONE_tevent::process: FLUSH for blk %d/%d rescheduled, repeat_count=%d\n", + adu->get_seq(), blk->seq, this->repeat_count)) + return false; /* tevent re-scheduled */ + } + /* + * the FLUSH process is now over! + * no more FLUSH will be generated and the block is assumed to + * be reliably transmitted. + * do the cleanup work now... + * remove this block from tx_window and free memory. + */ + blk->set_tx_status(BLK_TSTATUS_DONE); + mclcb->tx_window.remove_block(mclcb, blk, true); + blk->remove_and_free_all_fec_dus(mclcb); // to do after remove_block + /* + * if ADU is in status ADU_TSTATUS_FINISH_TX, then it's worth + * seeing if all blocks of this ADU have been reliably + * delivered or not. If yes, then remove this ADU altogether... + */ + free_adu = true; + for (rem = adu->get_block_nb(), blk_tmp = adu->get_block_head(); + rem > 0; rem--, blk_tmp++) { + if (blk->get_tx_status() != BLK_TSTATUS_DONE) { + free_adu = false; + break; + } + } + if (free_adu) { + /* this function frees buffers but not the ADU object itself */ + adu->set_tx_status(ADU_TSTATUS_DONE); + adu->remove_and_free_all_buffers(mclcb); + } + + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_FLUSH_DONE_tevent::process: blk %d/%d over\n", + adu->get_seq(), blk->seq)) + return true; + +error: + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_FLUSH_DONE_tevent::process: ERROR\n")) + return true; +} + + +/****** RETX_DONE class *******************************************************/ + +/** + * Default constructor. + */ +mcl_tx_ctrl_RETX_DONE_tevent::mcl_tx_ctrl_RETX_DONE_tevent + (UINT32 adu_idf, + UINT32 block_idf) +{ + this->type = TX_CTRL_TEVENT_RETX_DONE; + this->adu_id = adu_idf; + this->block_id = block_idf; +} + + +/** + * Default destructor. + */ +mcl_tx_ctrl_RETX_DONE_tevent::~mcl_tx_ctrl_RETX_DONE_tevent () +{ +} + + +/** + * Find a RETX_DONE_tevent in an unordered list with a type-dependant criteria. + * @param mclcb + * @param head pointer to the list head pointer + * @return returns a pointer to the tevent if found, NULL otherwise + */ +mcl_tx_ctrl_RETX_DONE_tevent * +mcl_tx_ctrl_RETX_DONE_tevent::find_in_list (mcl_cb *const mclcb, + mcl_tx_ctrl_tevent **head) +{ + mcl_tx_ctrl_RETX_DONE_tevent *tevent; + mcl_tx_ctrl_RETX_DONE_tevent *nhead; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl_tevent::find_in_list:\n")) + ASSERT(head); + if (!(nhead = (mcl_tx_ctrl_RETX_DONE_tevent*)(*head))) { + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_tevent::find_in_list: empty list\n")) + return NULL; + } + /* + * start from the list tail + */ + tevent = (mcl_tx_ctrl_RETX_DONE_tevent*)(nhead->prev); + while (1) { + ASSERT(tevent); + if ((tevent->adu_id == this->adu_id) && + (tevent->block_id == this->block_id)) { + /* found */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_tevent::find_in_list: found\n")) + return tevent; + } + if (tevent == nhead) { + /* we have cycled and tevent is not in list */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_tevent::find_in_list: not found\n")) + return NULL; + } + tevent = (mcl_tx_ctrl_RETX_DONE_tevent*)tevent->prev; + } +} + + +/** + * Perform RETX_DONE_tevent specific processing. + */ +void +mcl_tx_ctrl_RETX_DONE_tevent::process (mcl_cb *const mclcb) +{ + mcl_adu *adu; + mcl_block *blk; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_ctrl_RETX_DONE_tevent::process:\n")) + /* find the adu first */ + if (!(adu = mclcb->tx.find_adu(mclcb, this->adu_id))) { + /* + * for some reason this ADU is not in tx window... give-up! + */ + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl_RETX_DONE_tevent::process: WARNING, adu not found in tx window\n")) + goto error; + } + /* then find the block */ + if (!(blk = adu->find_block(mclcb, this->block_id))) { + /* + * for some reason this block is not in tx window... give-up! + */ + TRACELVL(5, (mcl_stdout, "<- mcl_tx_ctrl_RETX_DONE_tevent::process: WARNING, block not found in tx window\n")) + goto error; + } + /* + * and now send a FLUSH packet for this block and create a new + * FLUSH_DONE tevent + */ + mclcb->tx_ctrl.send_flush_and_register_tevent(mclcb, blk); + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_RETX_DONE_tevent::process:\n")) + return; + +error: + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_ctrl_RETX_DONE_tevent::process: ERROR\n")) + return; +} + diff --git a/src/norm/mcl_tx_ctrl.h b/src/norm/mcl_tx_ctrl.h new file mode 100644 index 0000000..8151a7f --- /dev/null +++ b/src/norm/mcl_tx_ctrl.h @@ -0,0 +1,350 @@ +/* $Id: mcl_tx_ctrl.h,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_TX_CTRL_H +#define MCL_TX_CTRL_H + +/** + * Sender's control tasks. + * This class is used for NORM control message transmission and reception + * (if applicable) at a sender. + * This class inherits the timer_handler class in order to have a timer + * callback function. + */ +class mcl_tx_ctrl : public mcl_timer_handler { + +public: + /****** Public Members ************************************************/ + + /** + * Default constructor. + */ + mcl_tx_ctrl(); + + /** + * See if any control packet must be sent or not, and send it if + * necessary. + * This function is called just after the transmission of a DU + * (end_session false) or at the end of the session (end_session + * true). + * @param mclcb + * @param du DU that has just been sent + * @param end_session boolean true after the transmission of + * the last DU of the last block of a session. + * Used to trigger the tx of a FLUSH + */ + void check_if_ctrl_pkt_must_be_sent (mcl_cb *const mclcb, + mcl_du *du, + bool end_session); + + /** + * Send NORM_CMD(FLUSH) packet(s) and register a FLUSH_DONE + * timer event. + * @param mclcb + * @param blk block for which we need to send a FLUSH + */ + void send_flush_and_register_tevent (mcl_cb *const mclcb, + mcl_block *blk); + + /** + * Send NORM_CMD(FLUSH) packet(s). + * @param mclcb + * @param blk block for which we need to send a FLUSH + */ + void send_flush_pkt (mcl_cb *const mclcb, + mcl_block *blk); + + /** + * Send NORM_CMD(NO_NEW_OBJECT) packet(s). + */ + void send_no_new_object_pkt (mcl_cb *const mclcb); + + /** + * Send NORM_CMD(CLOSE) packet(s). + */ + void send_close_pkt (mcl_cb *const mclcb); + + /** + * Process an incoming NORM_NACK packet. + * @param mclcb + * @param pkt pointer to packet + * @param saddr source address for this packet + * @param chdr_infos pointer to the common_infos struct + */ + mcl_error_status process_nack_pkt (mcl_cb *const mclcb, + class mcl_rx_pkt *pkt, + mcl_addr *saddr, + mcl_common_hdr_infos_t *chdr_infos); + + /** + * timer callback method. + * @param arg1 mclcb + * @param arg2 pointer to a tx_ctrl_timer_event_t struct + */ + virtual void timer_callback (INT32 arg1, INT32 arg2); + + /** + * See if there is one or more registered pending control + * operations (i.e. tevent). + * @param mclcb + * @return true if there is one or more pending ctrl operation + */ + bool is_there_pending_ctrl (mcl_cb *const mclcb); + + + /****** Public Attributes *********************************************/ + + /** + * + * @param XXX explanation + * @return Completion status (MCL_OK or MCL_ERROR). + */ + +private: + /****** Private Members ***********************************************/ + + /** + * Send NORM_CMD(any flavor) packet(s). + * Sends MCL_TX_ROBUSTNESS_FACTOR copies of the packet. + * Used by send_no_new_object_pkt() and send_close_pkt() functions. + * @param mclcb + * @param flavor flavor of the command packet + * @param du only required for NORM_CMD_FLUSH + */ + void send_cmd_pkt (mcl_cb *const mclcb, + norm_cmd_flavor flavor, + mcl_du *du); + + /****** Private Attributes ********************************************/ + + /** + * Used by check_if_ctrl_pkt_must_be_sent() to identify a change + * of block and/or ADU being sent. + */ + mcl_block *blk_of_last_du; + + /** + * Create a list of pending timer_events. + * Required for instance to avoid duplicated timer_events. + * There is one list per tevent type. + */ + class mcl_tx_ctrl_tevent *FLUSH_DONE_tevent_head; + class mcl_tx_ctrl_tevent *RETX_DONE_tevent_head; +}; + + +/** + * Types of timer events. + * WARNING: must be in line with list of mcl_tx_ctrl_tevent::get_type_string() + */ +enum mcl_tx_ctrl_tevent_types { + TX_CTRL_TEVENT_INVALID = 0, + TX_CTRL_TEVENT_FLUSH_DONE, + TX_CTRL_TEVENT_RETX_DONE +}; + + +/** + * This base class describes timer events. + * This is the second arg of timer_callback() method. + */ +class mcl_tx_ctrl_tevent { + +public: + /****** Public Members ************************************************/ + + /** + * No default constructor. + */ + + /** + * Default destructor. + */ + virtual ~mcl_tx_ctrl_tevent (); + +#ifdef DEBUG + /** Return the tevent type as a static string. */ + char *get_type_string () const; +#endif + + /** + * Timer-specific processing function + */ + + /** + * Insert a tevent in an unordered list. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ + mcl_error_status insert_in_list (mcl_cb *const mclcb, + mcl_tx_ctrl_tevent **head); + + /** + * Remove a tevent from an unordered list. + * Called with the appropriate list head parameter. + * @param mclcb + * @param head pointer to the list head pointer + */ + mcl_error_status remove_from_list (mcl_cb *const mclcb, + mcl_tx_ctrl_tevent **head); + + + /****** Public Attributes *********************************************/ + + mcl_tx_ctrl_tevent_types type; + + +protected: + /****** Protected Members *********************************************/ + /****** Protected Attributes ******************************************/ + mcl_tx_ctrl_tevent *prev, *next; + + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + +}; + + +/** + * This class describes the FLUSH_DONE timer event. + * It is derived from the mcl_tx_ctrl_tevent base class. + * This tevent is used to remenber a FLUSH has been sent + * and take appropriate measures if no NACK are received + * at timeout (e.g. free memory from list). + */ +class mcl_tx_ctrl_FLUSH_DONE_tevent : public mcl_tx_ctrl_tevent { + +public: + /****** Public Members ************************************************/ + + /** + * Default constructor. + * @param adu_idf ADU for which this FLUSH_DONE_tevent pertains + * @param block_idf block within this ADU for which this + * FLUSH_DONE_tevent pertains + */ + mcl_tx_ctrl_FLUSH_DONE_tevent (UINT32 adu_idf, + UINT32 block_idf); + + /** + * Default destructor. + */ + virtual ~mcl_tx_ctrl_FLUSH_DONE_tevent (); + + /** + * Perform FLUSH_DONE_tevent specific processing. + * @return true if tevent is completed and should be free'ed and + * removed from list, false if it has been re-scheduled. + */ + bool process (mcl_cb *const mclcb); + + /** + * Find a FLUSH_DONE_tevent in an unordered list with type-dependant + * criteria. + * Compares the adu_id and block_id arguments. + * @param mclcb + * @param head pointer to the list head pointer + * @return returns a pointer to the tevent if found, NULL otherwise + */ + mcl_tx_ctrl_FLUSH_DONE_tevent *find_in_list + (mcl_cb *const mclcb, + mcl_tx_ctrl_tevent **head); + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + UINT32 adu_id; // for this NORM_CMD_FLUSH + UINT32 block_id; // for this NORM_CMD_FLUSH + /** + * a FLUSH with no answer should be repeated for improved robustness. + * this is the nb of repeatitions remaining. + */ + UINT32 repeat_count; + +}; + + +/** + * This class describes the RETX_DONE timer event. + * It is derived from the mcl_tx_ctrl_tevent base class. + * This tevent is used to register FLUSH events to send in the future. + */ +class mcl_tx_ctrl_RETX_DONE_tevent : public mcl_tx_ctrl_tevent { + +public: + /****** Public Members ************************************************/ + + /** + * Default constructor. + * @param adu_idf ADU for which this RETX_DONE_tevent pertains + * @param block_idf block within this ADU for which this + * RETX_DONE_tevent pertains + */ + mcl_tx_ctrl_RETX_DONE_tevent (UINT32 adu_idf, + UINT32 block_idf); + + /** + * Default destructor. + */ + virtual ~mcl_tx_ctrl_RETX_DONE_tevent (); + + /** + * Perform RETX_DONE_tevent specific processing. + */ + void process (mcl_cb *const mclcb); + + /** + * Find a RETX_DONE_tevent in an unordered list with type-dependant + * criteria. + * Compares the adu_id and block_id arguments. + * @param mclcb + * @param head pointer to the list head pointer + * @return returns a pointer to the tevent if found, NULL otherwise + */ + mcl_tx_ctrl_RETX_DONE_tevent *find_in_list + (mcl_cb *const mclcb, + mcl_tx_ctrl_tevent **head); + + + /****** Public Attributes *********************************************/ + + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + UINT32 adu_id; // for this NORM_CMD_FLUSH + UINT32 block_id; // for this NORM_CMD_FLUSH + +}; + + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +#endif // !MCL_TX_CTRL_H diff --git a/src/norm/mcl_tx_storage.cpp b/src/norm/mcl_tx_storage.cpp new file mode 100644 index 0000000..cd41f8a --- /dev/null +++ b/src/norm/mcl_tx_storage.cpp @@ -0,0 +1,110 @@ +/* $Id: mcl_tx_storage.cpp,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +mcl_tx_storage::mcl_tx_storage () +{ +} + +mcl_tx_storage::~mcl_tx_storage () +{ +} + + +mcl_error_status +mcl_tx_storage::store_adu_data (mcl_cb *const mclcb, + mcl_adu *const adu, + char *const buf) +{ + INT32 len; // buf actual length + INT32 padded_len; // buf padded length to comply with FEC req. + char *pbuf; // permanent MCL internal buffer + + /* + * store in physical tx memory (ptm) + */ + ASSERT(adu); + len = adu->get_len(); + padded_len = adu->get_padded_len(); + if (mclcb->tx.can_reuse_appli_buf()) { + // take control of buf and avoid an extra data copy + if (padded_len != len) { + // add a null padding to end of block + if (!(pbuf = (char*)realloc((void*)buf, padded_len))) { + goto no_mem; + } + memset(pbuf + len, 0, padded_len - len);/* padding */ + } else { + pbuf = buf; // use the appli buffer + } + } else { + // copy data in a private buffer + if (!(pbuf = (char*)malloc(padded_len))) { + goto no_mem; + } + memcpy(pbuf, buf, len); + memset(pbuf + len, 0, padded_len - len); /* padding */ + } + adu->set_data_ptr(pbuf); + return MCL_OK; + +no_mem: + PRINT_ERR((mcl_stderr, "mcl_tx_storage::store_du_data: ERROR: out of memory\n")) + return MCL_ERROR; +} + + +mcl_error_status +mcl_tx_storage::store_du_data (mcl_cb *const mclcb, + mcl_du *const du, + char *const buf) +{ + du->data = buf; + return MCL_OK; +#if 0 + INT32 len; // buf actual length + char *pbuf; // permanent MCL internal buffer + + /* + * store in physical tx memory (ptm) + */ + ASSERT(du); + len = du->get_len(); + if (mclcb->tx.can_reuse_appli_buf()) { + // take control of buf and avoid an extra data copy + // nothing to do here... + } else { + // copy data in a private buffer + if (!(pbuf = (char*)malloc(len))) { + goto no_mem; + } + memcpy(pbuf, buf, len); + } + du->set_data_ptr(pbuf); + return MCL_OK; + +no_mem: + PRINT_ERR((mcl_stderr, "mcl_tx_storage::store_du_data: ERROR: out of memory\n")) + return MCL_ERROR; +#endif // 0 +} diff --git a/src/norm/mcl_tx_storage.h b/src/norm/mcl_tx_storage.h new file mode 100644 index 0000000..c9fb56b --- /dev/null +++ b/src/norm/mcl_tx_storage.h @@ -0,0 +1,79 @@ +/* $Id: mcl_tx_storage.h,v 1.2 2004/01/30 16:27:43 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_TX_STORAGE_H +#define MCL_TX_STORAGE_H + +/** + * Class explanation + */ +class mcl_tx_storage { + +public: + /****** Public Members ************************************************/ + mcl_tx_storage (); + ~mcl_tx_storage (); + + /** + * store data buffer in a private internal tx buffer and update adu ptr. + * @param mclcb + * @param adu adu to which buffer belongs + * @param buf buffer whose content needs to be stored in a permanent + * location (typically this buf is allocated by the upper + * application) + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status store_adu_data (mcl_cb *const mclcb, + mcl_adu *const adu, + char *const buf); + + /** + * store data buffer in a private internal tx buffer and update du ptr. + * @param mclcb + * @param du du to which buffer belongs + * @param buf buffer whose content needs to be stored in a permanent + * location + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status store_du_data (mcl_cb *const mclcb, + mcl_du *const du, + char *const buf); + + /****** Public Attributes *********************************************/ + + /** + * + * @param XXX explanation + * @return Completion status (MCL_OK or MCL_ERROR). + */ + +private: + /****** Private Members ***********************************************/ + /****** Private Attributes ********************************************/ + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +#endif // !MCL_TX_STORAGE_H diff --git a/src/norm/mcl_tx_window.cpp b/src/norm/mcl_tx_window.cpp new file mode 100644 index 0000000..b7a13e5 --- /dev/null +++ b/src/norm/mcl_tx_window.cpp @@ -0,0 +1,453 @@ +/* $Id: mcl_tx_window.cpp,v 1.3 2004/02/18 07:56:18 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "mcl_includes.h" + + +/** + * default constructor + */ +mcl_tx_window::mcl_tx_window () +{ + memset((void*)this, 0, sizeof(*this)); + this->blist_size = DFLT_BLIST_SIZE; // in blocks + this->seq_tx_in_hp_count = MAX_SEQ_TX_FROM_HP; +} + + +/** + * default destructor + */ +mcl_tx_window::~mcl_tx_window () +{ +} + + +/** + * Is it possible to register a new ADU? + * Performs flow control between the upper application and MCL. + * For simplicity, does not take into account the ADU data size, + * it just checks if there is any room left. + * This is not required for DU registration, since they are + * generated internally by MCL, not by the application. + * @return boolean + */ +bool +mcl_tx_window::can_register_new_adu (mcl_cb *const mclcb) +{ + if (mclcb->fsm.no_new_adu(mclcb)) { + // not possible, mcl_close() already called. + return false; + } + return (this->blist_eff_size < this->blist_size); +} + + +/** + * Register a new adu (i.e. all of its data DUs and FEC DUs if any) + * for transmission in the sending window. + * The DUs are inserted in a NORMAL PRIORITY list. + * @return Completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_tx_window::register_new_adu (mcl_cb *const mclcb, + mcl_adu *const adu) +{ + mcl_block *blk; + mcl_du *du; + INT32 b_rem; // remaining nb of blocks to process + INT32 d_rem; // remaining nb of DUs to process + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_window::register_new_adu:\n")) + for (b_rem = adu->get_block_nb(), blk = adu->get_block_head(); + b_rem > 0; b_rem--, blk++) { + ASSERT((blk)) + /* register data DUs */ + for (d_rem = blk->du_nb, du = blk->get_du_head(); + d_rem > 0; d_rem--, du++) { + ASSERT(du); + this->insert_in_list(mclcb, du); + } +#if 0 + /* register FEC DUs (if any) */ + for (d_rem = blk->get_fec_du_nb_in_list(), du = blk->get_fec_du_head(); + d_rem > 0; d_rem--, du = du->get_next()) { + ASSERT(du); + this->insert_in_list(mclcb, du); + } +#endif + } + // TODO: blist management... + this->blist_eff_size += adu->get_block_nb(); + TRACELVL(5, (mcl_stdout, "<- mcl_tx_window::register_new_adu: ok\n")) + return MCL_OK; +} + + +/** + * Register a new FEC du for transmission in the sending window. + * @return Completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_tx_window::register_new_du (mcl_cb *const mclcb, + mcl_du *const du) +{ + TRACELVL(5, (mcl_stdout, "-> mcl_tx_window::register_new_du:\n")) + this->insert_in_hp_list(mclcb, du); + TRACELVL(5, (mcl_stdout, "<- mcl_tx_window::register_new_du: ok\n")) + return MCL_OK; +} + + +/** + * Reschedule transmissions (data and/or FEC DUs) for a block. + * Reschedule the transmission of all available FEC, and if not + * sufficient, retransmit data. + * @param mclcb + * @param blk block that must be retransmitted entirely + * @param data_required nb of data DUs to transmit (>= 0) + * @param fec_required nb of FEC DUs to transmit (>= 0) + */ +mcl_error_status +mcl_tx_window::reschedule_tx_for_block (mcl_cb *const mclcb, + mcl_block *blk, + INT32 data_required, + INT32 fec_required) +{ + mcl_du *du; + INT32 d_rem; // remaining nb of DUs to process + INT32 fec_to_tx; // nb of FEC DUs to tx immediately + + TRACELVL(1, (mcl_stdout, + "-> mcl_tx_window::reschedule_tx_for_block: requires %d/%d DUs for blk %d/%d\n", + data_required, fec_required, blk->adu->get_seq(), blk->seq)) + ASSERT(blk); + ASSERT(data_required <= blk->du_nb); + if (data_required > 0) { + /* register data DUs */ + for (d_rem = blk->du_nb, du = blk->get_du_head(); + d_rem > 0; d_rem--, du++) { + ASSERT(du); + this->insert_in_list(mclcb, du); + } + } + if (fec_required > 0) { + /* + * calculate how many FEC DUs to create for future tx and + * to tx immediately + */ + if (fec_required > blk->get_fec_du_nb_in_list()) { + /* not enough FEC available, schedule creation of new ones */ + // TODO: + fec_to_tx = blk->get_fec_du_nb_in_list(); + } else + fec_to_tx = fec_required; + /* register FEC DUs (if any) */ + for (d_rem = fec_to_tx, du = blk->get_fec_du_head(); + d_rem > 0; d_rem--, du = du->get_next()) { + ASSERT(du); + this->insert_in_list(mclcb, du); + } + } + TRACELVL(5, (mcl_stdout, "<- mcl_tx_window::reschedule_tx_for_block:\n")) + return MCL_OK; +} + + +/** + * Remove a block from the transmission window. + * Called usually when the block has been sent reliably (e.g. + * at the end of a FLUSH_DONE process). + * @param mclcb + * @param blk block to remove + * @param fast_mode in fast mode it is assumed there is no pending + * DU transmission for this block + * @return completion status (MCL_OK or MCL_ERROR). + */ +mcl_error_status +mcl_tx_window::remove_block (mcl_cb *const mclcb, + mcl_block *const blk, + bool fast_mode) +{ + UINT32 d_rem; // remaining nb of DUs to process + mcl_du *du; + + TRACELVL(5, (mcl_stdout, "-> mcl_tx_window::remove_block:\n")) + if (fast_mode == false) { + /* + * go through the whole list, and if any pending transmission + * for this block exist, remove it. + */ + for (d_rem = blk->du_nb, du = blk->get_du_head(); + d_rem > 0; d_rem--, du++) { + ASSERT(du); + if (this->remove_from_list(mclcb, du) == MCL_ERROR) { + /* maybe it's on the HP list, try to remove */ + this->remove_from_hp_list(mclcb, du); + } + } + for (d_rem = blk->get_fec_du_nb_in_list(), du = blk->get_fec_du_head(); + d_rem > 0; d_rem--, du++) { + ASSERT(du); + this->remove_from_hp_list(mclcb, du); + } + } + /* + * unregister... + */ + this->blist_eff_size--; + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_window::remove_block: blist_eff_sz=%d, available room=%d blks\n", + this->blist_eff_size, this->blist_size - this->blist_eff_size)) + return MCL_OK; +} + + +/** + * Returns the next DU to send, in either of the two lists. + * This DU is automatically removed from the associated list. + */ +mcl_du * +mcl_tx_window::get_next_du_to_tx (mcl_cb *const mclcb) +{ + mcl_du *du; + + /* + * start with the HP list... + */ + if (!(this->hp_du_list_head)) { + /* nothing available... */ + goto try_other_du_list; + } + /* + * serve MAX_SEQ_TX_FROM_HP pkts from HP list, then 1 from normal + * list (if one is available, otherwise stay with the HP list). + * Doing so avoids starvation. + */ + if ((this->seq_tx_in_hp_count <= 0) && (this->du_list_head)) { + /* switch to the normal list */ + this->seq_tx_in_hp_count = this->MAX_SEQ_TX_FROM_HP; + goto try_other_du_list; + } + this->seq_tx_in_hp_count = max(this->seq_tx_in_hp_count - 1, 0); + /* remove from start of list */ + du = this->hp_du_list_head; + this->nb_of_du_in_hp_list--; + if (this->nb_of_du_in_hp_list >= 1) { + this->hp_du_list_head = du->get_tx_next(); + du->get_tx_next()->set_tx_prev(du->get_tx_prev()); + du->get_tx_prev()->set_tx_next(du->get_tx_next()); + } else { + /* list turns empty */ + this->hp_du_list_head = NULL; + } + ASSERT( (this->nb_of_du_in_hp_list > 0 && this->hp_du_list_head) || + (this->nb_of_du_in_hp_list == 0 && this->hp_du_list_head == NULL)); + TRACELVL(5, (mcl_stdout, + " mcl_tx_window::get_next_du_to_tx: HP list, du seq=%d\n", du->seq)) + return du; + +try_other_du_list: + /* + * and if needed continue with normal priority list... + */ + if (!(this->du_list_head)) { + /* nothing available... */ + TRACELVL(5, (mcl_stdout, + " mcl_tx_window::get_next_du_to_tx: none\n")) + return NULL; + } + /* remove from start of list */ + du = this->du_list_head; + this->nb_of_du_in_list--; + if (this->nb_of_du_in_list >= 1) { + this->du_list_head = du->get_tx_next(); + du->get_tx_next()->set_tx_prev(du->get_tx_prev()); + du->get_tx_prev()->set_tx_next(du->get_tx_next()); + } else { + /* list turns empty */ + this->du_list_head = NULL; + } + ASSERT( (this->nb_of_du_in_list > 0 && this->du_list_head) || + (this->nb_of_du_in_list == 0 && this->du_list_head == NULL)); + TRACELVL(5, (mcl_stdout, + " mcl_tx_window::get_next_du_to_tx: normal list, du seq=%d\n", du->seq)) + return du; +} + + +void +mcl_tx_window::insert_in_list (mcl_cb *const mclcb, + mcl_du *const du) +{ + mcl_du *last; // temp pointer to last du in list + + TRACELVL(5, (mcl_stdout, + "-> mcl_tx_window::insert_in_list: du=x%x, seq=%d\n", + (int)du, du->seq)) + this->nb_of_du_in_list++; + if (!(this->du_list_head)) { + /* + * first du in list + */ + ASSERT(!(this->du_list_snd_max)); + this->du_list_head = du; + du->set_tx_next(du); + du->set_tx_prev(du); + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_window::insert_in_list: ok, inserted in empty list\n")) + return; + } + /* + * add at end of list + */ + last = this->du_list_head->get_tx_prev(); + ASSERT(last); + last->set_tx_next(du); + du->set_tx_prev(last); + du->set_tx_next(this->du_list_head); + this->du_list_head->set_tx_prev(du); + + TRACELVL(5, (mcl_stdout, "<- mcl_tx_window::insert_in_list:\n")) +} + + +mcl_error_status +mcl_tx_window::remove_from_list (mcl_cb *const mclcb, + mcl_du *const du) +{ + mcl_du *next, *prev; // temp pointers + UINT32 d_rem; // remaining nb of DUs to process + + TRACELVL(5, (mcl_stdout, + "-> mcl_tx_window::remove_from_list: du=x%x, seq=%d\n", + (int)du, du->seq)) + if (!(next = this->du_list_head)) { + /* no du in list */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_window::remove_from_list: ERROR, empty list\n")) + return MCL_ERROR; + } + /* + * search in entire list + */ + for (d_rem = this->nb_of_du_in_list; d_rem > 0; + d_rem--, next = next->get_tx_next()) { + if (next == du) { + /* found */ + prev = du->get_prev(); + next = du->get_next(); + prev->set_tx_next(next); + next->set_tx_prev(prev); + if (du == this->du_list_head) + this->du_list_head = next; + if (du == this->du_list_snd_max) + this->du_list_snd_max = next; + this->nb_of_du_in_list--; + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_window::remove_from_list: found and removed\n")) + return MCL_OK; + } + } + /* du not found in list */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_window::remove_from_list: ERROR, not found in list\n")) + return MCL_ERROR; +} + + +void +mcl_tx_window::insert_in_hp_list (mcl_cb *const mclcb, + mcl_du *const du) +{ + mcl_du *last; // temp pointer to last du in list + + TRACELVL(5, (mcl_stdout, + "-> mcl_tx_window::insert_in_hp_list: du=x%x, seq=%d\n", + (int)du, du->seq)) + this->nb_of_du_in_hp_list++; + if (!(this->hp_du_list_head)) { + /* + * first du in list + */ + ASSERT(!(this->hp_du_list_snd_max)); + this->hp_du_list_head = du; + du->set_tx_next(du); + du->set_tx_prev(du); + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_window::insert_in_hp_list: ok, inserted in empty list\n")) + return; + } + /* + * add at end of list + */ + last = this->hp_du_list_head->get_tx_prev(); + ASSERT(last); + last->set_tx_next(du); + du->set_tx_prev(last); + du->set_tx_next(this->hp_du_list_head); + this->hp_du_list_head->set_tx_prev(du); + + TRACELVL(5, (mcl_stdout, "<- mcl_tx_window::insert_in_hp_list:\n")) +} + + +mcl_error_status +mcl_tx_window::remove_from_hp_list (mcl_cb *const mclcb, + mcl_du *const du) +{ + mcl_du *next, *prev; // temp pointers + UINT32 d_rem; // remaining nb of DUs to process + + TRACELVL(5, (mcl_stdout, + "-> mcl_tx_window::remove_from_hp_list: du=x%x, seq=%d\n", + (int)du, du->seq)) + if (!(next = this->hp_du_list_head)) { + /* no du in hp_list */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_window::remove_from_hp_list: ERROR, empty list\n")) + return MCL_ERROR; + } + /* + * search in entire hp_list + */ + for (d_rem = this->nb_of_du_in_hp_list; d_rem > 0; d_rem--, next = next->get_tx_next()) { + if (next == du) { + /* found */ + prev = du->get_prev(); + next = du->get_next(); + prev->set_tx_next(next); + next->set_tx_prev(prev); + if (du == this->hp_du_list_head) + this->hp_du_list_head = next; + if (du == this->hp_du_list_snd_max) + this->hp_du_list_snd_max = next; + this->nb_of_du_in_hp_list--; + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_window::remove_from_hp_list: found and removed\n")) + return MCL_OK; + } + } + /* du not found in hp_list */ + TRACELVL(5, (mcl_stdout, + "<- mcl_tx_window::remove_from_hp_list: ERROR, not found in list\n")) + return MCL_ERROR; +} diff --git a/src/norm/mcl_tx_window.h b/src/norm/mcl_tx_window.h new file mode 100644 index 0000000..5498b72 --- /dev/null +++ b/src/norm/mcl_tx_window.h @@ -0,0 +1,278 @@ +/* $Id: mcl_tx_window.h,v 1.3 2004/02/18 07:56:18 roca Exp $ */ +/* + * Copyright (c) 2004 INRIA - All rights reserved + * (main author: Vincent Roca - vincent.roca@inrialpes.fr) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MCL_TX_WINDOW_H +#define MCL_TX_WINDOW_H + + + +/** + * This class provides all the required services to manage the transmission + * window at the sender. + * It enables all the data DUs of an ADU plus its FEC DUs (if any) to be + * registered for transmission. + */ +class mcl_tx_window { + +public: + /****** Public Members ************************************************/ + /** + * default constructor + */ + mcl_tx_window (); + + /** + * default destructor + */ + ~mcl_tx_window (); + + /** + * Is it possible to register a new ADU? + * Performs flow control between the upper application and MCL. + * For simplicity, does not take into account the ADU data size, + * it just checks if there is any room left. + * This is not required for DU registration, since they are + * generated internally by MCL, not by the application. + * @return boolean + */ + bool can_register_new_adu (mcl_cb *const mclcb); + + /** + * Register a new adu (i.e. all of its data DUs and FEC DUs if any) + * for transmission in the sending window. + * The DUs are inserted in a NORMAL PRIORITY list. + * @return Completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status register_new_adu (mcl_cb *const mclcb, + mcl_adu *const adu); + + /** + * Register a new FEC or data DU for transmission in the sending + * window. + * The DUs are inserted in a HIGH PRIORITY list. + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status register_new_du (mcl_cb *const mclcb, + mcl_du *const du); + + /** + * * Reschedule transmissions (data and/or FEC DUs) for a block. + * Reschedule the transmission of all available FEC, and if not + * sufficient, retransmit data. + * @param mclcb + * @param blk block that must be retransmitted entirely + * @param data_required nb of data DUs to transmit (>= 0) + * @param fec_required nb of FEC DUs to transmit (>= 0) + */ + mcl_error_status reschedule_tx_for_block (mcl_cb *const mclcb, + mcl_block *blk, + INT32 data_required, + INT32 fec_required); + + /** + * Remove a block from the transmission window. + * Called usually when the block has been sent reliably (e.g. + * at the end of a FLUSH_DONE process). + * @param mclcb + * @param blk block to remove + * @param fast_mode in fast mode it is assumed there is no pending + * DU transmission for this block + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status remove_block (mcl_cb *const mclcb, + mcl_block *const blk, + bool fast_mode); + + /** + * Return the number of available data and FEC DUs for transmissions + * in either the normaL or high priority DU list. + * The returned value may be smaller than the total number of du + * registered, because some DUs may have already been sent. + */ + INT32 get_nb_of_available_du_to_tx (); + + /** + * Return the number of data or FEC du registered in the normal + * priority list. + * This value is most of the time strictly larger than that + * returned by get_nb_of_available_du_to_tx(). + */ + INT32 get_nb_of_registered_du (); + + /** + * Return the number of data or FEC du registered in the high + * priority list. + * This value is most of the time small since they usually concern + * retransmitted DUs and additional FEC DUs. + */ + INT32 get_nb_of_registered_hp_du (); + + /** + * Returns the next DU to send, in either of the two lists. + * This DU is automatically removed from the associated list. + */ + mcl_du *get_next_du_to_tx (mcl_cb *const mclcb); + + /****** Public Attributes *********************************************/ + + /** + * + * @param XXX explanation + * @return Completion status (MCL_OK or MCL_ERROR). + */ + +private: + /****** Private Members ***********************************************/ + /** + * Insert a DU in the normal priority list. + * @param du data or FEC DU to insert + */ + void insert_in_list (mcl_cb *const mclcb, mcl_du *const du); + + /** + * Insert a DU in the high priority list. + * @param du data or FEC DU to insert + */ + void insert_in_hp_list (mcl_cb *const mclcb, mcl_du *const du); + + /** + * Remove a DU from the normal priority list, if found. + * @param du data or FEC DU to remove + * @return completion status (MCL_OK or MCL_ERROR). + */ + mcl_error_status remove_from_list (mcl_cb *const mclcb, + mcl_du *const du); + + /** + * Remove a DU from the normal priority list, if found. + * @param du data or FEC DU to remove + * @return completion status (MCL_OK or MCL_ERROR). + */ + + mcl_error_status remove_from_hp_list (mcl_cb *const mclcb, + mcl_du *const du); + + /****** Private Attributes ********************************************/ + + /** + * Sending application / MCL flow control system: + * + * There is a tx window, consisting in a doubly linked list of blocks. + * Some of these blocks: + * - have been sent and ack'ed... They'll probably soon be free'd. + * - have been fully sent but not yet fully ack'ed... The sender + * is still waiting for ACKs/NAKs and is ready for retx. + * - have been partially sent + * Next DU transmissions will probably take place for + * this block. + * - have not yet been sent + * + * The following variables are used: + * blist_head head of list of blocks in tx window + * blist_tail its tail + * blist_snd_una oldest unacknowledged block sent + * blist_snd_max transmissions have occured up to this block + * blist_size theoretical window size (in blocks) + * blist_eff_size effective size (in blocks) + * + * ========> sent and ack'ed + * ============ sent blocks =========> + * <======= window size ============> + * <======= effective size ================> + * ---------[+-----------------------+]--------------+]----> [block] # + * ^ ^ ^ ^ + * | | | | + * head snd_una snd_max tail + * + * There can be more blocks in list than in theory + * (i.e. blist_eff_size > blist_size) because ADUs are submitted + * as a whole, and all the blocks are inserted in the list, + * even if they exceed the expected window size. + * The advantage is that an ADU will always be accepted as a whole, + * never partially. + * A major drawback is that very large ADUs can easily fool the + * system. So the ADU size should be kept reasonable (e.g. the + * application should segment huge files if necessary). + */ + + /** Block list (blist). */ + mcl_block *blist_head; + mcl_block *blist_tail; + mcl_block *blist_snd_una; + mcl_block *blist_snd_max; + INT32 blist_size; // in blocks + INT32 blist_eff_size; // in blocks + static const INT32 DFLT_BLIST_SIZE = 100; // default, in blocks + + /** + * And here is the corresponding DU lists. + * There is one for normal DUs (usually data DUs, sometimes also FEC + * DUs if proactive FEC is used), and another one for high priority + * DUs (e.g. in case of retransmissions, or if additional FEC DUs are + * calculated for loss recovery). + * The following policy applies: + * - serve the FEC list in priority. These FEC DUs are created + * in case for loss recovery and should be sent first + * whenever some exist. + * - never send a FEC DU before the first data DU of an ADU. + * in ever it would took place, then move the FEC DU + * in the du_list at the corresponding place. + * - then serve the normal DU list. + * - once transmitted, DUs are automatically removed from the + * list. It does not mean they are free'd though. In + * order to schedule a retransmission, the DU should + * be registered once again. + */ + /** Normal DU list (du_list). */ + mcl_du *du_list_head; + /** transmission already took place up to and including this DU. */ + mcl_du *du_list_snd_max; + /** counter */ + INT32 nb_of_du_in_list; + + /** High Priority DU list (hp_list). */ + mcl_du *hp_du_list_head; + /** transmission already took place up to and including this DU. */ + mcl_du *hp_du_list_snd_max; + /** counter */ + INT32 nb_of_du_in_hp_list; + + /** + * Serve MAX_SEQ_TX_FROM_HP pkts from the HP list, and then one + * from the normal list. + */ + static const INT32 MAX_SEQ_TX_FROM_HP = 2; + INT32 seq_tx_in_hp_count; /** counter */ + +}; + + +//------------------------------------------------------------------------------ +// Inlines for all classes follow +//------------------------------------------------------------------------------ + +inline INT32 +mcl_tx_window::get_nb_of_available_du_to_tx () +{ + return (this->nb_of_du_in_list + this->nb_of_du_in_hp_list); +} + +#endif // !MCL_TX_WINDOW_H diff --git a/src/sdp_lib/COPYING b/src/sdp_lib/COPYING new file mode 100644 index 0000000..f3f1b3b --- /dev/null +++ b/src/sdp_lib/COPYING @@ -0,0 +1,504 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it becomes +a de-facto standard. To achieve this, non-free programs must be +allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/src/sdp_lib/Changes b/src/sdp_lib/Changes new file mode 100644 index 0000000..fc237e7 --- /dev/null +++ b/src/sdp_lib/Changes @@ -0,0 +1,38 @@ +Changelog for SinisterSdp. +-------------------------------------------------------------------------------- + +[0.80] +Fixed two infinite loop bugs in _ParseContactField(). Also fixed the +SDP_AssertTrue() macro, and fixed a memory leak in _ParseRepeatTimeField(). +The SinisterSdpDescriptions documentation has been improved too. + +[0.75] +Heavily cleaned up the Parser code. Added error codes specific to each type of +field and added more error checking in general. The SDP_EventStreamParser +module was also improved. Many more comments were added as well. + +[0.70] +Moved the linked list macros from SDP_Utility.h to their own header file, +SDP_LinkedList. Also created a new internal struct similar to SDP_Str to +encapsulate lists with few other macros to manipulate it. Moved some of the +string manipulation code from SDP_Generator.c to SDP_Str.c, and flushed out the +SDP_Str module more. + +[0.60] +Shipping now with documentation in HTML and POD format. + +[0.50] +Fixed up some of the generator functions, and also added functions to generate +from each type of structure. Also added custom assertion macros and sprinkled +calls to them throughout the code. + +[0.40] +Added a large module to encapsulate the structures used to store parsed values +from a description. This module provides New(), Get(), Set(), and Destroy() +functions for each object. Also moved _SplitField() into its own module, +SDP_StreamTokenizer. + +[0.07] + +Initial release. + diff --git a/src/sdp_lib/MANIFEST b/src/sdp_lib/MANIFEST new file mode 100644 index 0000000..9fd3dcf --- /dev/null +++ b/src/sdp_lib/MANIFEST @@ -0,0 +1,33 @@ +COPYING +Changes +MANIFEST +README +SinisterSdp.html +SinisterSdp.pod +SinisterSdpDescriptions.html +SinisterSdpDescriptions.pod +SinisterSdpError.html +SinisterSdpError.pod +SinisterSdpGenerator.html +SinisterSdpGenerator.pod +SinisterSdpParser.html +SinisterSdpParser.pod +src/Makefile +src/SDP_Description.c +src/SDP_Description.h +src/SDP_Error.c +src/SDP_Error.h +src/SDP_EventStreamParser.c +src/SDP_EventStreamParser.h +src/SDP_Generator.c +src/SDP_Generator.h +src/SDP_LinkedList.h +src/SDP_Parser.c +src/SDP_Parser.h +src/SDP_Str.c +src/SDP_Str.h +src/SDP_StreamTokenizer.c +src/SDP_StreamTokenizer.h +src/SDP_Utility.c +src/SDP_Utility.h +src/SinisterSdp.h diff --git a/src/sdp_lib/README b/src/sdp_lib/README new file mode 100644 index 0000000..7335f95 --- /dev/null +++ b/src/sdp_lib/README @@ -0,0 +1,45 @@ +SinisterSdp - An open source Session Description Protocol library. +------------------------------------------------------------------ + +INTRODUCTION + +SinisterSdp is an open source ANSI C library that parses and generates Session +Description Protocol session descriptions for multimedia streaming and VoIP +(Voice over Internet Protocol). The Session Description Protocol is described +in RFC 2327 (http://www.ietf.org/rfc/rfc2327.txt). + +INSTALLATION + +To install, go to the ./src subdirectory and run the following commands: + + $ make + $ make install + $ make clean + +The makefile takes a few options, most notably: LIBRARY_DESTINATION and +HEADER_DESTINATION. The first is the path to the directory where the resulting +*.a archive will go, and the second is the path to where the main SinisterSdp.h +header file will go and where a ./SDP sub directory will be created to store +the rest of the header files. + +There are several more options too. Read the Makefile for details. + +There is also an alternate target you can specify to just build the generator +by itself if you need only that. (The parser utilizes the generator, so you can +build the generator without the parser but not the other way around). + +GETTING STARTED + +See the SinisterSdp.html file for info on how to get started. + +COPYRIGHT + +Copyright 2004 by William G. Davis. + +This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. diff --git a/src/sdp_lib/SinisterSdp.html b/src/sdp_lib/SinisterSdp.html new file mode 100644 index 0000000..e1cf78f --- /dev/null +++ b/src/sdp_lib/SinisterSdp.html @@ -0,0 +1,168 @@ + + + + +SinisterSdp.pod + + + + + + +
+

NAME

+ +

SinisterSdp - A C library for parsing and generating SDP session descriptions

+

SYNOPSIS

+ +
 #include <SDP/SDP_Parser.h>
+ #include <SDP/SDP_Generator.h>
+ ...
+
+
+

DESCRIPTION

+ +

SinisterSdp is an open source ANSI C library that parses and generates Session +Description Protocol session descriptions for multimedia streaming and VoIP +(Voice over Internet Protocol). The Session Description Protocol is described +in RFC 2327 (http://www.ietf.org/rfc/rfc2327.txt).

+

This library is divided up into two main components: a parser and a generator. +See the SinisterSdpParser and +SinisterSdpGenerator documents for how to use +each. SinisterSdpDescriptions describes +how to use the structures that encapsulate SDP descriptions, and +SinisterSdpError.html details the mechanisms by which +SinisterSdp handles errors.

+

BUILDING

+ +

To build SinisterSdp, just edit and run the Makefile in the "src" directory to +create a binary you can statically link to. See the README file for full +instructions.

+

BUGS

+ +

Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse

+

You can also email me directly: +<william_g_davis at users dot sourceforge dot net>.

+

COPYRIGHT

+ +

Copyright 2004 by William G. Davis.

+

This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution.

+

This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE.

+ + +
diff --git a/src/sdp_lib/SinisterSdp.pod b/src/sdp_lib/SinisterSdp.pod new file mode 100644 index 0000000..e512af5 --- /dev/null +++ b/src/sdp_lib/SinisterSdp.pod @@ -0,0 +1,53 @@ +=head1 NAME + +SinisterSdp - A C library for parsing and generating SDP session descriptions + +=head1 SYNOPSIS + + #include + #include + ... + +=head1 DESCRIPTION + +SinisterSdp is an open source ANSI C library that parses and generates Session +Description Protocol session descriptions for multimedia streaming and VoIP +(Voice over Internet Protocol). The Session Description Protocol is described +in RFC 2327 (http://www.ietf.org/rfc/rfc2327.txt). + +This library is divided up into two main components: a parser and a generator. +See the L and +L documents for how to use +each. L describes +how to use the structures that encapsulate SDP descriptions, and +L details the mechanisms by which +SinisterSdp handles errors. + +=head1 BUILDING + +To build SinisterSdp, just edit and run the Makefile in the "src" directory to +create a binary you can statically link to. See the README file for full +instructions. + +=head1 BUGS + +Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse + +You can also email me directly: +. + +=head1 COPYRIGHT + +Copyright 2004 by William G. Davis. + +This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. + +=cut + diff --git a/src/sdp_lib/SinisterSdpDescriptions.html b/src/sdp_lib/SinisterSdpDescriptions.html new file mode 100644 index 0000000..5a659b8 --- /dev/null +++ b/src/sdp_lib/SinisterSdpDescriptions.html @@ -0,0 +1,3743 @@ + + + + +SinisterSdpDescriptions.pod + + + + +
+ +
+ +
+

NAME

+ +

SinisterSdpDescriptions - Routines to manipulate descriptions.

+

SYNOPSIS

+ +
 #include <SDP/SDP_Description.h>
+ 
+ int main(void)
+ {
+ 	SDP_Description *description = SDP_NewDescription();
+ 	SDP_SetProtocolVersion(description, 1);
+ 	SDP_SetSessionName(description, "Session Name");
+ 	...
+ }
+
+
+

DESCRIPTION

+ +

This document describes how to use SDP_Description structs.

+

These structs are returned by the SinisterSdp parser functions and manpulated +using a series of Get/Set, Add/Remove, and New/Destroy routines. +You'll probably only end up using the Get routines and maybe a few of the Set +routines, but the others are always there if you need them.

+

The functions that return "const char *" return pointers to internal string +buffers. If you need to modify them, then use strdup() or something similar to +copy them, then modify the copy.

+

FUNCTIONS

+ +

The following routines are available:

+

CONSTRUCTOR FUNCTIONS

+ +

These functions create and return new structs to encapsulate some portion of an +SDP description.

+

SDP_NewDescription()

+ +
 SDP_Description *SDP_NewDescription(void);
+
+
+

This function creates a new SDP_Description struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_Description struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_Description struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewOwner()

+ +
 SDP_Owner *SDP_NewOwner(void);
+
+
+

This function creates a new SDP_Owner struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_Owner struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_Owner struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewEmailContact()

+ +
 SDP_EmailContact *SDP_NewEmailContact(void);
+
+
+

This function creates a new SDP_EmailContact struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_EmailContact struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_EmailContact struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewPhoneContact()

+ +
 SDP_PhoneContact *SDP_NewPhoneContact(void);
+
+
+

This function creates a new SDP_PhoneContact struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_PhoneContact struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_PhoneContact struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewConnection()

+ +
 SDP_Connection *SDP_NewConnection(void);
+
+
+

This function creates a new SDP_Connection struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_Connection struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_Connection struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewBandwidth()

+ +
 SDP_Bandwidth *SDP_NewBandwidth(void);
+
+
+

This function creates a new SDP_Bandwidth struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_Bandwidth struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_Bandwidth struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewSessionPlayTime()

+ +
 SDP_SessionPlayTime *SDP_NewSessionPlayTime(void);
+
+
+

This function creates a new SDP_SessionPlayTime struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_SessionPlayTime struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_SessionPlayTime struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewRepeatTime()

+ +
 SDP_RepeatTime *SDP_NewRepeatTime(void);
+
+
+

This function creates a new SDP_RepeatTime struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_RepeatTime struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_RepeatTime struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewZoneAdjustment()

+ +
 SDP_ZoneAdjustment *SDP_NewZoneAdjustment(void);
+
+
+

This function creates a new SDP_ZoneAdjustment struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_ZoneAdjustment struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_ZoneAdjustment struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewEncryption()

+ +
 SDP_Encryption *SDP_NewEncryption(void);
+
+
+

This function creates a new SDP_Encryption struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_Encryption struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_Encryption struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewAttribute()

+ +
 SDP_Attribute *SDP_NewAttribute(void);
+
+
+

This function creates a new SDP_Attribute struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_Attribute struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_Attribute struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_NewMediaDescription()

+ +
 SDP_MediaDescription *SDP_NewMediaDescription(void);
+
+
+

This function creates a new SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_MediaDescription struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_MediaDescription struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

"SET" ACCESSOR FUNCTIONS

+ +

These functions enable you to set values within structs that encapsulates +portions of an SDP description.

+

SDP_SetProtocolVersion(description, version)

+ +
 void SDP_SetProtocolVersion(
+ 	SDP_Description *   description,
+ 	int                 version
+ );
+
+
+

This function sets the protocol version within an SDP_Description +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct.

      +
    • version
    • +

      The version.

      +
    +
+

SDP_SetOwner(description, username, session_id, session_version, network_type, address_type, address)

+ +
 int SDP_SetOwner(
+ 	SDP_Description *   description,
+ 	const char *        username,
+ 	const char *        session_id,
+ 	const char *        session_version,
+ 	const char *        network_type,
+ 	const char *        address_type,
+ 	const char *        address
+ );
+
+
+

This function sets the owner within an SDP_Description +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the owner.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct.

      +
    • username
    • +

      A pointer to a string containing the username.

      +
    • session_id
    • +

      A pointer to a string containing the session id.

      +
    • session_version
    • +

      A pointer to a string containing the session version.

      +
    • network_type
    • +

      A pointer to a string containing the network type.

      +
    • address_type
    • +

      A pointer to a string containing the address type.

      +
    • address
    • +

      A pointer to a string containing the address.

      +
    +
+

SDP_SetUsername(owner, username)

+ +
 int SDP_SetUsername(
+ 	SDP_Owner *    owner,
+ 	const char *   username
+ );
+
+
+

This function sets the username within an SDP_Owner +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the username.
    +
    +
    +
  • Parameters
  • +
      +
    • owner
    • +

      A pointer to the SDP_Owner struct.

      +
    • username
    • +

      A pointer to a string containing the username.

      +
    +
+

SDP_SetSessionID(owner, session_id)

+ +
 int SDP_SetSessionID(
+ 	SDP_Owner *    owner,
+ 	const char *   session_id
+ );
+
+
+

This function sets the session iD within an SDP_Owner +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the session iD.
    +
    +
    +
  • Parameters
  • +
      +
    • owner
    • +

      A pointer to the SDP_Owner struct.

      +
    • session_id
    • +

      A pointer to a string containing the session id.

      +
    +
+

SDP_SetSessionVersion(owner, session_version)

+ +
 int SDP_SetSessionVersion(
+ 	SDP_Owner *    owner,
+ 	const char *   session_version
+ );
+
+
+

This function sets the session version within an SDP_Owner +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the session version.
    +
    +
    +
  • Parameters
  • +
      +
    • owner
    • +

      A pointer to the SDP_Owner struct.

      +
    • session_version
    • +

      A pointer to a string containing the session version.

      +
    +
+

SDP_SetOwnerNetworkType(owner, network_type)

+ +
 int SDP_SetOwnerNetworkType(
+ 	SDP_Owner *    owner,
+ 	const char *   network_type
+ );
+
+
+

This function sets the owner network type within an SDP_Owner +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the owner network type.
    +
    +
    +
  • Parameters
  • +
      +
    • owner
    • +

      A pointer to the SDP_Owner struct.

      +
    • network_type
    • +

      A pointer to a string containing the network type.

      +
    +
+

SDP_SetOwnerAddressType(owner, address_type)

+ +
 int SDP_SetOwnerAddressType(
+ 	SDP_Owner *    owner,
+ 	const char *   address_type
+ );
+
+
+

This function sets the owner address type within an SDP_Owner +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the owner address type.
    +
    +
    +
  • Parameters
  • +
      +
    • owner
    • +

      A pointer to the SDP_Owner struct.

      +
    • address_type
    • +

      A pointer to a string containing the address type.

      +
    +
+

SDP_SetOwnerAddress(owner, address)

+ +
 int SDP_SetOwnerAddress(
+ 	SDP_Owner *    owner,
+ 	const char *   address
+ );
+
+
+

This function sets the owner address within an SDP_Owner +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the owner address.
    +
    +
    +
  • Parameters
  • +
      +
    • owner
    • +

      A pointer to the SDP_Owner struct.

      +
    • address
    • +

      A pointer to a string containing the address.

      +
    +
+

SDP_SetSessionName(description, session_name)

+ +
 int SDP_SetSessionName(
+ 	SDP_Description *   description,
+ 	const char *        session_name
+ );
+
+
+

This function sets the session name within an SDP_Description +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the session name.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct.

      +
    • session_name
    • +

      A pointer to a string containing the session name.

      +
    +
+

SDP_SetSessionInformation(description, session_information)

+ +
 int SDP_SetSessionInformation(
+ 	SDP_Description *   description,
+ 	const char *        session_information
+ );
+
+
+

This function sets the session information within an SDP_Description +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the session information.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct.

      +
    • session_information
    • +

      A pointer to a string containing the session information.

      +
    +
+

SDP_SetURI(description, uri)

+ +
 int SDP_SetURI(
+ 	SDP_Description *   description,
+ 	const char *        uri
+ );
+
+
+

This function sets the URI within an SDP_Description +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the URI.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct.

      +
    • uri
    • +

      A pointer to a string containing the uri.

      +
    +
+

SDP_AddEmailContact(description, email_contact)

+ +
 void SDP_AddEmailContact(
+ 	SDP_Description *    description,
+ 	SDP_EmailContact *   email_contact
+ );
+
+
+

This function adds an SDP_EmailContact struct to the email contact +linked list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the email contact linked list.

      +
    • email_contact
    • +

      A pointer to the SDP_EmailContact struct to add.

      +
    +
+

SDP_AddNewEmailContact(description, address, name)

+ +
 int SDP_AddNewEmailContact(
+ 	SDP_Description *   description,
+ 	const char *        address,
+ 	const char *        name
+ );
+
+
+

This function creates and adds a new email contact to the +email contact linked list.

+
    +
  • Return Value
  • +

    If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call SDP_GetLastError(). The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to create and add the email contact.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the email contact linked list.

      +
    • address
    • +

      A pointer to a string containing the address.

      +
    • name
    • +

      A pointer to a string containing the name.

      +
    +
+

SDP_SetEmailAddress(email_contact, address)

+ +
 int SDP_SetEmailAddress(
+ 	SDP_EmailContact *   email_contact,
+ 	const char *         address
+ );
+
+
+

This function sets the email address within an SDP_EmailContact +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the email address.
    +
    +
    +
  • Parameters
  • +
      +
    • email_contact
    • +

      A pointer to the SDP_EmailContact struct.

      +
    • address
    • +

      A pointer to a string containing the address.

      +
    +
+

SDP_SetEmailName(email_contact, name)

+ +
 int SDP_SetEmailName(
+ 	SDP_EmailContact *   email_contact,
+ 	const char *         name
+ );
+
+
+

This function sets the email name within an SDP_EmailContact +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the email name.
    +
    +
    +
  • Parameters
  • +
      +
    • email_contact
    • +

      A pointer to the SDP_EmailContact struct.

      +
    • name
    • +

      A pointer to a string containing the name.

      +
    +
+

SDP_AddPhoneContact(description, phone_contact)

+ +
 void SDP_AddPhoneContact(
+ 	SDP_Description *    description,
+ 	SDP_PhoneContact *   phone_contact
+ );
+
+
+

This function adds an SDP_PhoneContact struct to the phone contact +linked list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the phone contact linked list.

      +
    • phone_contact
    • +

      A pointer to the SDP_PhoneContact struct to add.

      +
    +
+

SDP_AddNewPhoneContact(description, number, name)

+ +
 int SDP_AddNewPhoneContact(
+ 	SDP_Description *   description,
+ 	const char *        number,
+ 	const char *        name
+ );
+
+
+

This function creates and adds a new phone contact to the +phone contact linked list.

+
    +
  • Return Value
  • +

    If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call SDP_GetLastError(). The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to create and add the phone contact.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the phone contact linked list.

      +
    • number
    • +

      A pointer to a string containing the number.

      +
    • name
    • +

      A pointer to a string containing the name.

      +
    +
+

SDP_SetPhoneNumber(phone_contact, number)

+ +
 int SDP_SetPhoneNumber(
+ 	SDP_PhoneContact *   phone_contact,
+ 	const char *         number
+ );
+
+
+

This function sets the phone number within an SDP_PhoneContact +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the phone number.
    +
    +
    +
  • Parameters
  • +
      +
    • phone_contact
    • +

      A pointer to the SDP_PhoneContact struct.

      +
    • number
    • +

      A pointer to a string containing the number.

      +
    +
+

SDP_SetPhoneName(phone_contact, name)

+ +
 int SDP_SetPhoneName(
+ 	SDP_PhoneContact *   phone_contact,
+ 	const char *        name
+ );
+
+
+

This function sets the phone name within an SDP_PhoneContact +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the phone name.
    +
    +
    +
  • Parameters
  • +
      +
    • phone_contact
    • +

      A pointer to the SDP_PhoneContact struct.

      +
    • name
    • +

      A pointer to a string containing the name.

      +
    +
+

SDP_SetConnection(description, network_type, address_type, address, ttl, total_addresses)

+ +
 int SDP_SetConnection(
+ 	SDP_Description *   description,
+ 	const char *        network_type,
+ 	const char *        address_type,
+ 	const char *        address,
+ 	int                 ttl,
+ 	int                 total_addresses
+ );
+
+
+

This function sets the connection within an SDP_Description +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the connection.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct.

      +
    • network_type
    • +

      A pointer to a string containing the network type.

      +
    • address_type
    • +

      A pointer to a string containing the address type.

      +
    • address
    • +

      A pointer to a string containing the address.

      +
    • ttl
    • +

      The ttl.

      +
    • total_addresses
    • +

      The total addresses.

      +
    +
+

SDP_SetConnectionNetworkType(connection, network_type)

+ +
 int SDP_SetConnectionNetworkType(
+ 	SDP_Connection *   connection,
+ 	const char *       network_type
+ );
+
+
+

This function sets the connection network type within an SDP_Connection +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the connection network type.
    +
    +
    +
  • Parameters
  • +
      +
    • connection
    • +

      A pointer to the SDP_Connection struct.

      +
    • network_type
    • +

      A pointer to a string containing the network type.

      +
    +
+

SDP_SetConnectionAddressType(connection, address_type)

+ +
 int SDP_SetConnectionAddressType(
+ 	SDP_Connection *   connection,
+ 	const char *       address_type
+ );
+
+
+

This function sets the connection address type within an SDP_Connection +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the connection address type.
    +
    +
    +
  • Parameters
  • +
      +
    • connection
    • +

      A pointer to the SDP_Connection struct.

      +
    • address_type
    • +

      A pointer to a string containing the address type.

      +
    +
+

SDP_SetConnectionAddress(connection, address)

+ +
 int SDP_SetConnectionAddress(
+ 	SDP_Connection *   connection,
+ 	const char *       address
+ );
+
+
+

This function sets the connection address within an SDP_Connection +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the connection address.
    +
    +
    +
  • Parameters
  • +
      +
    • connection
    • +

      A pointer to the SDP_Connection struct.

      +
    • address
    • +

      A pointer to a string containing the address.

      +
    +
+

SDP_SetConnectionTTL(connection, ttl)

+ +
 void SDP_SetConnectionTTL(
+ 	SDP_Connection *   connection,
+ 	int                ttl
+ );
+
+
+

This function sets the connection tTL within an SDP_Connection +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • connection
    • +

      A pointer to the SDP_Connection struct.

      +
    • ttl
    • +

      The ttl.

      +
    +
+

SDP_SetTotalConnectionAddresses(connection, total_addresses)

+ +
 void SDP_SetTotalConnectionAddresses(
+ 	SDP_Connection *   connection,
+ 	int                total_addresses
+ );
+
+
+

This function sets the total connection addresses within an SDP_Connection +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • connection
    • +

      A pointer to the SDP_Connection struct.

      +
    • total_addresses
    • +

      The total addresses.

      +
    +
+

SDP_SetBandwidth(description, modifier, value)

+ +
 int SDP_SetBandwidth(
+ 	SDP_Description *   description,
+ 	const char *        modifier,
+ 	long                value
+ );
+
+
+

This function sets the bandwidth within an SDP_Description +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the bandwidth.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct.

      +
    • modifier
    • +

      A pointer to a string containing the modifier.

      +
    • value
    • +

      The value.

      +
    +
+

SDP_SetBandwidthModifier(bandwidth, modifier)

+ +
 int SDP_SetBandwidthModifier(
+ 	SDP_Bandwidth *   bandwidth,
+ 	const char *      modifier
+ );
+
+
+

This function sets the bandwidth modifier within an SDP_Bandwidth +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the bandwidth modifier.
    +
    +
    +
  • Parameters
  • +
      +
    • bandwidth
    • +

      A pointer to the SDP_Bandwidth struct.

      +
    • modifier
    • +

      A pointer to a string containing the modifier.

      +
    +
+

SDP_SetBandwidthValue(bandwidth, value)

+ +
 void SDP_SetBandwidthValue(
+ 	SDP_Bandwidth *   bandwidth,
+ 	long              value
+ );
+
+
+

This function sets the bandwidth value within an SDP_Bandwidth +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • bandwidth
    • +

      A pointer to the SDP_Bandwidth struct.

      +
    • value
    • +

      The value.

      +
    +
+

SDP_AddSessionPlayTime(description, session_play_time)

+ +
 void SDP_AddSessionPlayTime(
+ 	SDP_Description *       description,
+ 	SDP_SessionPlayTime *   session_play_time
+ );
+
+
+

This function adds an SDP_SessionPlayTime struct to the session play time +linked list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the session play time linked list.

      +
    • session_play_time
    • +

      A pointer to the SDP_SessionPlayTime struct to add.

      +
    +
+

SDP_AddNewSessionPlayTime(description, start_time, end_time)

+ +
 int SDP_AddNewSessionPlayTime(
+ 	SDP_Description *   description,
+ 	time_t              start_time,
+ 	time_t              end_time
+ );
+
+
+

This function creates and adds a new session play time to the +session play time linked list.

+
    +
  • Return Value
  • +

    If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call SDP_GetLastError(). The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to create and add the session play time.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the session play time linked list.

      +
    • start_time
    • +

      The start time.

      +
    • end_time
    • +

      The end time.

      +
    +
+

SDP_SetStartTime(session_play_time, start_time)

+ +
 void SDP_SetStartTime(
+ 	SDP_SessionPlayTime *   session_play_time,
+ 	time_t                  start_time
+ );
+
+
+

This function sets the start time within an SDP_SessionPlayTime +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      A pointer to the SDP_SessionPlayTime struct.

      +
    • start_time
    • +

      The start time.

      +
    +
+

SDP_SetEndTime(session_play_time, end_time)

+ +
 void SDP_SetEndTime(
+ 	SDP_SessionPlayTime *   session_play_time,
+ 	time_t                  end_time
+ );
+
+
+

This function sets the end time within an SDP_SessionPlayTime +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      A pointer to the SDP_SessionPlayTime struct.

      +
    • end_time
    • +

      The end time.

      +
    +
+

SDP_AddRepeatTime(session_play_time, repeat_time)

+ +
 void SDP_AddRepeatTime(
+ 	SDP_SessionPlayTime *   session_play_time,
+ 	SDP_RepeatTime *        repeat_time
+ );
+
+
+

This function adds an SDP_RepeatTime struct to the repeat time +linked list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      A pointer to the SDP_SessionPlayTime struct containing the repeat time linked list.

      +
    • repeat_time
    • +

      A pointer to the SDP_RepeatTime struct to add.

      +
    +
+

SDP_AddNewRepeatTime(session_play_time, repeat_interval, active_duration, repeat_offsets, total_offsets)

+ +
 int SDP_AddNewRepeatTime(
+ 	SDP_SessionPlayTime *   session_play_time,
+ 	unsigned long           repeat_interval,
+ 	unsigned long           active_duration,
+ 	const unsigned long     repeat_offsets[],
+ 	int                     total_offsets
+ );
+
+
+

This function creates and adds a new repeat time to the +repeat time linked list.

+
    +
  • Return Value
  • +

    If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call SDP_GetLastError(). The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to create and add the repeat time.
    +
    +
    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      A pointer to the SDP_SessionPlayTime struct containing the repeat time linked list.

      +
    • repeat_interval
    • +

      The repeat interval.

      +
    • active_duration
    • +

      The active duration.

      +
    • repeat_offsets
    • +

      The repeat offsets.

      +
    • total_offsets
    • +

      The total offsets.

      +
    +
+

SDP_SetRepeatInterval(repeat_time, repeat_interval)

+ +
 void SDP_SetRepeatInterval(
+ 	SDP_RepeatTime *   repeat_time,
+ 	unsigned long      repeat_interval
+ );
+
+
+

This function sets the repeat interval within an SDP_RepeatTime +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      A pointer to the SDP_RepeatTime struct.

      +
    • repeat_interval
    • +

      The repeat interval.

      +
    +
+

SDP_SetActiveDuration(repeat_time, active_duration)

+ +
 void SDP_SetActiveDuration(
+ 	SDP_RepeatTime *   repeat_time,
+ 	unsigned long      active_duration
+ );
+
+
+

This function sets the active duration within an SDP_RepeatTime +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      A pointer to the SDP_RepeatTime struct.

      +
    • active_duration
    • +

      The active duration.

      +
    +
+

SDP_SetRepeatOffsets(repeat_time, repeat_offsets, total_offsets)

+ +
 int SDP_SetRepeatOffsets(
+ 	SDP_RepeatTime *      repeat_time,
+ 	const unsigned long   repeat_offsets[],
+ 	int                   total_offsets
+ );
+
+
+

This function sets the repeat offsets within an SDP_RepeatTime +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the repeat offsets.
    +
    +
    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      A pointer to the SDP_RepeatTime struct.

      +
    • repeat_offsets
    • +

      The repeat offsets.

      +
    • total_offsets
    • +

      The total offsets.

      +
    +
+

SDP_AddZoneAdjustment(description, zone_adjustment)

+ +
 void SDP_AddZoneAdjustment(
+ 	SDP_Description *      description,
+ 	SDP_ZoneAdjustment *   zone_adjustment
+ );
+
+
+

This function adds an SDP_ZoneAdjustment struct to the zone adjustment +linked list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the zone adjustment linked list.

      +
    • zone_adjustment
    • +

      A pointer to the SDP_ZoneAdjustment struct to add.

      +
    +
+

SDP_AddNewZoneAdjustment(description, time, offset)

+ +
 int SDP_AddNewZoneAdjustment(
+ 	SDP_Description *   description,
+ 	time_t              time,
+ 	long                offset
+ );
+
+
+

This function creates and adds a new zone adjustment to the +zone adjustment linked list.

+
    +
  • Return Value
  • +

    If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call SDP_GetLastError(). The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to create and add the zone adjustment.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the zone adjustment linked list.

      +
    • time
    • +

      The time.

      +
    • offset
    • +

      The offset.

      +
    +
+

SDP_SetZoneAdjustmentTime(zone_adjustment, time)

+ +
 void SDP_SetZoneAdjustmentTime(
+ 	SDP_ZoneAdjustment *   zone_adjustment,
+ 	time_t                 time
+ );
+
+
+

This function sets the zone adjustment time within an SDP_ZoneAdjustment +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • zone_adjustment
    • +

      A pointer to the SDP_ZoneAdjustment struct.

      +
    • time
    • +

      The time.

      +
    +
+

SDP_SetZoneAdjustmentOffset(zone_adjustment, offset)

+ +
 void SDP_SetZoneAdjustmentOffset(
+ 	SDP_ZoneAdjustment *   zone_adjustment,
+ 	long                   offset
+ );
+
+
+

This function sets the zone adjustment offset within an SDP_ZoneAdjustment +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • zone_adjustment
    • +

      A pointer to the SDP_ZoneAdjustment struct.

      +
    • offset
    • +

      The offset.

      +
    +
+

SDP_SetEncryption(description, method, key)

+ +
 int SDP_SetEncryption(
+ 	SDP_Description *   description,
+ 	const char *        method,
+ 	const char *        key
+ );
+
+
+

This function sets the encryption within an SDP_Description +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the encryption.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct.

      +
    • method
    • +

      A pointer to a string containing the method.

      +
    • key
    • +

      A pointer to a string containing the key.

      +
    +
+

SDP_SetEncryptionMethod(encryption, method)

+ +
 int SDP_SetEncryptionMethod(
+ 	SDP_Encryption *   encryption,
+ 	const char *       method
+ );
+
+
+

This function sets the encryption method within an SDP_Encryption +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the encryption method.
    +
    +
    +
  • Parameters
  • +
      +
    • encryption
    • +

      A pointer to the SDP_Encryption struct.

      +
    • method
    • +

      A pointer to a string containing the method.

      +
    +
+

SDP_SetEncryptionKey(encryption, key)

+ +
 int SDP_SetEncryptionKey(
+ 	SDP_Encryption *   encryption,
+ 	const char *       key
+ );
+
+
+

This function sets the encryption key within an SDP_Encryption +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the encryption key.
    +
    +
    +
  • Parameters
  • +
      +
    • encryption
    • +

      A pointer to the SDP_Encryption struct.

      +
    • key
    • +

      A pointer to a string containing the key.

      +
    +
+

SDP_AddAttribute(description, attribute)

+ +
 void SDP_AddAttribute(
+ 	SDP_Description *   description,
+ 	SDP_Attribute *     attribute
+ );
+
+
+

This function adds an SDP_Attribute struct to the attribute +linked list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the attribute linked list.

      +
    • attribute
    • +

      A pointer to the SDP_Attribute struct to add.

      +
    +
+

SDP_AddNewAttribute(description, name, value)

+ +
 int SDP_AddNewAttribute(
+ 	SDP_Description *   description,
+ 	const char *        name,
+ 	const char *        value
+ );
+
+
+

This function creates and adds a new attribute to the +attribute linked list.

+
    +
  • Return Value
  • +

    If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call SDP_GetLastError(). The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to create and add the attribute.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the attribute linked list.

      +
    • name
    • +

      A pointer to a string containing the name.

      +
    • value
    • +

      A pointer to a string containing the value.

      +
    +
+

SDP_SetAttributeName(attribute, name)

+ +
 int SDP_SetAttributeName(
+ 	SDP_Attribute *   attribute,
+ 	const char *      name
+ );
+
+
+

This function sets the attribute name within an SDP_Attribute +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the attribute name.
    +
    +
    +
  • Parameters
  • +
      +
    • attribute
    • +

      A pointer to the SDP_Attribute struct.

      +
    • name
    • +

      A pointer to a string containing the name.

      +
    +
+

SDP_SetAttributeValue(attribute, value)

+ +
 int SDP_SetAttributeValue(
+ 	SDP_Attribute *   attribute,
+ 	const char *      value
+ );
+
+
+

This function sets the attribute value within an SDP_Attribute +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the attribute value.
    +
    +
    +
  • Parameters
  • +
      +
    • attribute
    • +

      A pointer to the SDP_Attribute struct.

      +
    • value
    • +

      A pointer to a string containing the value.

      +
    +
+

SDP_AddMediaDescription(description, media_description)

+ +
 void SDP_AddMediaDescription(
+ 	SDP_Description *        description,
+ 	SDP_MediaDescription *   media_description
+ );
+
+
+

This function adds an SDP_MediaDescription struct to the media description +linked list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the media description linked list.

      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct to add.

      +
    +
+

SDP_AddNewMediaDescription(description, media_type, port, total_ports, transport_protocol, formats, media_information)

+ +
 int SDP_AddNewMediaDescription(
+ 	SDP_Description *   description,
+ 	const char *        media_type,
+ 	unsigned short      port,
+ 	unsigned short      total_ports,
+ 	const char *        transport_protocol,
+ 	const char *        formats,
+ 	const char *        media_information
+ );
+
+
+

This function creates and adds a new media description to the +media description linked list.

+
    +
  • Return Value
  • +

    If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call SDP_GetLastError(). The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to create and add the media description.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the media description linked list.

      +
    • media_type
    • +

      A pointer to a string containing the media type.

      +
    • port
    • +

      The port.

      +
    • total_ports
    • +

      The total ports.

      +
    • transport_protocol
    • +

      A pointer to a string containing the transport protocol.

      +
    • formats
    • +

      A pointer to a string containing the formats.

      +
    • media_information
    • +

      A pointer to a string containing the media information.

      +
    +
+

SDP_SetMediaType(media_description, media_type)

+ +
 int SDP_SetMediaType(
+ 	SDP_MediaDescription *   media_description,
+ 	const char *             media_type
+ );
+
+
+

This function sets the media type within an SDP_MediaDescription +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the media type.
    +
    +
    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct.

      +
    • media_type
    • +

      A pointer to a string containing the media type.

      +
    +
+

SDP_SetMediaPort(media_description, port)

+ +
 void SDP_SetMediaPort(
+ 	SDP_MediaDescription *   media_description,
+ 	unsigned short           port
+ );
+
+
+

This function sets the media port within an SDP_MediaDescription +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct.

      +
    • port
    • +

      The port.

      +
    +
+

SDP_SetTotalMediaPorts(media_description, total_ports)

+ +
 void SDP_SetTotalMediaPorts(
+ 	SDP_MediaDescription *   media_description,
+ 	unsigned short           total_ports
+ );
+
+
+

This function sets the total media ports within an SDP_MediaDescription +struct.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct.

      +
    • total_ports
    • +

      The total ports.

      +
    +
+

SDP_SetMediaTransportProtocol(media_description, transport_protocol)

+ +
 int SDP_SetMediaTransportProtocol(
+ 	SDP_MediaDescription *   media_description,
+ 	const char *             transport_protocol
+ );
+
+
+

This function sets the media transport protocol within an SDP_MediaDescription +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the media transport protocol.
    +
    +
    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct.

      +
    • transport_protocol
    • +

      A pointer to a string containing the transport protocol.

      +
    +
+

SDP_SetMediaFormats(media_description, formats)

+ +
 int SDP_SetMediaFormats(
+ 	SDP_MediaDescription *   media_description,
+ 	const char *             formats
+ );
+
+
+

This function sets the media formats within an SDP_MediaDescription +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the media formats.
    +
    +
    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct.

      +
    • formats
    • +

      A pointer to a string containing the formats.

      +
    +
+

SDP_SetMediaInformation(media_description, media_information)

+ +
 int SDP_SetMediaInformation(
+ 	SDP_MediaDescription *   media_description,
+ 	const char *             media_information
+ );
+
+
+

This function sets the media information within an SDP_MediaDescription +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the media information.
    +
    +
    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct.

      +
    • media_information
    • +

      A pointer to a string containing the media information.

      +
    +
+

SDP_SetMediaConnection(media_description, network_type, address_type, address, ttl, total_addresses)

+ +
 int SDP_SetMediaConnection(
+ 	SDP_MediaDescription *   media_description,
+ 	const char *             network_type,
+ 	const char *             address_type,
+ 	const char *             address,
+ 	int                      ttl,
+ 	int                      total_addresses
+ );
+
+
+

This function sets the media connection within an SDP_MediaDescription +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the media connection.
    +
    +
    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct.

      +
    • network_type
    • +

      A pointer to a string containing the network type.

      +
    • address_type
    • +

      A pointer to a string containing the address type.

      +
    • address
    • +

      A pointer to a string containing the address.

      +
    • ttl
    • +

      The ttl.

      +
    • total_addresses
    • +

      The total addresses.

      +
    +
+

SDP_SetMediaBandwidth(media_description, modifier, value)

+ +
 int SDP_SetMediaBandwidth(
+ 	SDP_MediaDescription *   media_description,
+ 	const char *             modifier,
+ 	long                     value
+ );
+
+
+

This function sets the media bandwidth within an SDP_MediaDescription +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the media bandwidth.
    +
    +
    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct.

      +
    • modifier
    • +

      A pointer to a string containing the modifier.

      +
    • value
    • +

      The value.

      +
    +
+

SDP_SetMediaEncryption(media_description, method, key)

+ +
 int SDP_SetMediaEncryption(
+ 	SDP_MediaDescription *   media_description,
+ 	const char *             method,
+ 	const char *             key
+ );
+
+
+

This function sets the media encryption within an SDP_MediaDescription +struct.

+
    +
  • Return Value
  • +

    It returns true if no error occurs, false otherwise. For extended error +information call SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to set the media encryption.
    +
    +
    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct.

      +
    • method
    • +

      A pointer to a string containing the method.

      +
    • key
    • +

      A pointer to a string containing the key.

      +
    +
+

SDP_AddMediaAttribute(media_description, attribute)

+ +
 void SDP_AddMediaAttribute(
+ 	SDP_MediaDescription *   media_description,
+ 	SDP_Attribute *          attribute
+ );
+
+
+

This function adds an SDP_Attribute struct to the media attribute +linked list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct containing the media attribute linked list.

      +
    • attribute
    • +

      A pointer to the SDP_Attribute struct to add.

      +
    +
+

SDP_AddNewMediaAttribute(media_description, name, value)

+ +
 int SDP_AddNewMediaAttribute(
+ 	SDP_MediaDescription *   media_description,
+ 	const char *             name,
+ 	const char *             value
+ );
+
+
+

This function creates and adds a new media attribute to the +media attribute linked list.

+
    +
  • Return Value
  • +

    If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call SDP_GetLastError(). The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         to create and add the media attribute.
    +
    +
    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct containing the media attribute linked list.

      +
    • name
    • +

      A pointer to a string containing the name.

      +
    • value
    • +

      A pointer to a string containing the value.

      +
    +
+

"GET" ACCESSOR FUNCTIONS

+ +

These functions enable you to retrieve values from structs that encapsulates +portions of an SDP description.

+

SDP_GetNextDescription(description)

+ +
 #define SDP_GetNextDescription SDP_GetNext
+
+
+

Gets the next SDP_Description struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the next SDP_Description struct in the linked list or NULL if there is none.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to a SDP_Description struct.

      +
    +
+

SDP_GetPreviousDescription(description)

+ +
 #define SDP_GetPreviousDescription SDP_GetPrevious
+
+
+

Gets the previous SDP_Description struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the previous SDP_Description struct in the linked list, or NULL if there is none.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to a SDP_Description struct.

      +
    +
+

SDP_GetProtocolVersion(description)

+ +
 int SDP_GetProtocolVersion(SDP_Description *description);
+
+
+

This function retrieves the protocol version from an SDP_Description struct.

+
    +
  • Return Value
  • +

    The protocol version.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the protocol version from.

      +
    +
+

SDP_GetOwner(description)

+ +
 SDP_Owner *SDP_GetOwner(SDP_Description *description);
+
+
+

This function retrieves the owner from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the owner.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the owner from.

      +
    +
+

SDP_GetUsername(owner)

+ +
 const char *SDP_GetUsername(SDP_Owner *owner);
+
+
+

This function retrieves the username from an SDP_Owner struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the username.

    +
  • Parameters
  • +
      +
    • owner
    • +

      The SDP_Owner struct to retrieve the username from.

      +
    +
+

SDP_GetSessionID(owner)

+ +
 const char *SDP_GetSessionID(SDP_Owner *owner);
+
+
+

This function retrieves the session iD from an SDP_Owner struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the session iD.

    +
  • Parameters
  • +
      +
    • owner
    • +

      The SDP_Owner struct to retrieve the session iD from.

      +
    +
+

SDP_GetSessionVersion(owner)

+ +
 const char *SDP_GetSessionVersion(SDP_Owner *owner);
+
+
+

This function retrieves the session version from an SDP_Owner struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the session version.

    +
  • Parameters
  • +
      +
    • owner
    • +

      The SDP_Owner struct to retrieve the session version from.

      +
    +
+

SDP_GetOwnerNetworkType(owner)

+ +
 const char *SDP_GetOwnerNetworkType(SDP_Owner *owner);
+
+
+

This function retrieves the owner network type from an SDP_Owner struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the owner network type.

    +
  • Parameters
  • +
      +
    • owner
    • +

      The SDP_Owner struct to retrieve the owner network type from.

      +
    +
+

SDP_GetOwnerAddressType(owner)

+ +
 const char *SDP_GetOwnerAddressType(SDP_Owner *owner);
+
+
+

This function retrieves the owner address type from an SDP_Owner struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the owner address type.

    +
  • Parameters
  • +
      +
    • owner
    • +

      The SDP_Owner struct to retrieve the owner address type from.

      +
    +
+

SDP_GetOwnerAddress(owner)

+ +
 const char *SDP_GetOwnerAddress(SDP_Owner *owner);
+
+
+

This function retrieves the owner address from an SDP_Owner struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the owner address.

    +
  • Parameters
  • +
      +
    • owner
    • +

      The SDP_Owner struct to retrieve the owner address from.

      +
    +
+

SDP_GetSessionName(description)

+ +
 const char *SDP_GetSessionName(SDP_Description *description);
+
+
+

This function retrieves the session name from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the session name.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the session name from.

      +
    +
+

SDP_GetSessionInformation(description)

+ +
 const char *SDP_GetSessionInformation(SDP_Description *description);
+
+
+

This function retrieves the session information from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the session information.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the session information from.

      +
    +
+

SDP_GetURI(description)

+ +
 const char *SDP_GetURI(SDP_Description *description);
+
+
+

This function retrieves the URI from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the URI.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the URI from.

      +
    +
+

SDP_GetEmailContacts(description)

+ +
 SDP_EmailContact *SDP_GetEmailContacts(SDP_Description *description);
+
+
+

This function retrieves the email contacts from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the email contacts.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the email contacts from.

      +
    +
+

SDP_GetNextEmailContact(email_contact)

+ +
 #define SDP_GetNextEmailContact SDP_GetNext
+
+
+

Gets the next SDP_EmailContact struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the next SDP_EmailContact struct in the linked list or NULL if there is none.

    +
  • Parameters
  • +
      +
    • email_contact
    • +

      A pointer to a SDP_EmailContact struct.

      +
    +
+

SDP_GetPreviousEmailContact(email_contact)

+ +
 #define SDP_GetPreviousEmailContact SDP_GetPrevious
+
+
+

Gets the previous SDP_EmailContact struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the previous SDP_EmailContact struct in the linked list, or NULL if there is none.

    +
  • Parameters
  • +
      +
    • email_contact
    • +

      A pointer to a SDP_EmailContact struct.

      +
    +
+

SDP_GetEmailAddress(email_contact)

+ +
 const char *SDP_GetEmailAddress(SDP_EmailContact *email_contact);
+
+
+

This function retrieves the email address from an SDP_EmailContact struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the email address.

    +
  • Parameters
  • +
      +
    • email_contact
    • +

      The SDP_EmailContact struct to retrieve the email address from.

      +
    +
+

SDP_GetEmailName(email_contact)

+ +
 const char *SDP_GetEmailName(SDP_EmailContact *email_contact);
+
+
+

This function retrieves the email name from an SDP_EmailContact struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the email name.

    +
  • Parameters
  • +
      +
    • email_contact
    • +

      The SDP_EmailContact struct to retrieve the email name from.

      +
    +
+

SDP_RemoveEmailContact(description, email_contact)

+ +
 void SDP_RemoveEmailContact(
+ 	SDP_Description *    description,
+ 	SDP_EmailContact *   email_contact
+ );
+
+
+

This removes (but does not destroy) the specified SDP_EmailContact +struct from the email contact list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the list.

      +
    • email_contact
    • +

      A pointer to the SDP_EmailContact you want removed from the list.

      +
    +
+

SDP_GetPhoneContacts(description)

+ +
 SDP_PhoneContact *SDP_GetPhoneContacts(SDP_Description *description);
+
+
+

This function retrieves the phone contacts from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the phone contacts.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the phone contacts from.

      +
    +
+

SDP_GetNextPhoneContact(phone_contact)

+ +
 #define SDP_GetNextPhoneContact SDP_GetNext
+
+
+

Gets the next SDP_PhoneContact struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the next SDP_PhoneContact struct in the linked list or NULL if there is none.

    +
  • Parameters
  • +
      +
    • phone_contact
    • +

      A pointer to a SDP_PhoneContact struct.

      +
    +
+

SDP_GetPreviousPhoneContact(phone_contact)

+ +
 #define SDP_GetPreviousPhoneContact SDP_GetPrevious
+
+
+

Gets the previous SDP_PhoneContact struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the previous SDP_PhoneContact struct in the linked list, or NULL if there is none.

    +
  • Parameters
  • +
      +
    • phone_contact
    • +

      A pointer to a SDP_PhoneContact struct.

      +
    +
+

SDP_GetPhoneNumber(phone_contact)

+ +
 const char *SDP_GetPhoneNumber(SDP_PhoneContact *phone_contact);
+
+
+

This function retrieves the phone number from an SDP_PhoneContact struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the phone number.

    +
  • Parameters
  • +
      +
    • phone_contact
    • +

      The SDP_PhoneContact struct to retrieve the phone number from.

      +
    +
+

SDP_GetPhoneName(phone_contact)

+ +
 const char *SDP_GetPhoneName(SDP_PhoneContact *phone_contact);
+
+
+

This function retrieves the phone name from an SDP_PhoneContact struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the phone name.

    +
  • Parameters
  • +
      +
    • phone_contact
    • +

      The SDP_PhoneContact struct to retrieve the phone name from.

      +
    +
+

SDP_RemovePhoneContact(description, phone_contact)

+ +
 void SDP_RemovePhoneContact(
+ 	SDP_Description *    description,
+ 	SDP_PhoneContact *   phone_contact
+ );
+
+
+

This removes (but does not destroy) the specified SDP_PhoneContact +struct from the phone contact list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the list.

      +
    • phone_contact
    • +

      A pointer to the SDP_PhoneContact you want removed from the list.

      +
    +
+

SDP_GetConnection(description)

+ +
 SDP_Connection *SDP_GetConnection(SDP_Description *description);
+
+
+

This function retrieves the connection from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the connection.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the connection from.

      +
    +
+

SDP_GetConnectionNetworkType(connection)

+ +
 const char *SDP_GetConnectionNetworkType(SDP_Connection *connection);
+
+
+

This function retrieves the connection network type from an SDP_Connection struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the connection network type.

    +
  • Parameters
  • +
      +
    • connection
    • +

      The SDP_Connection struct to retrieve the connection network type from.

      +
    +
+

SDP_GetConnectionAddressType(connection)

+ +
 const char *SDP_GetConnectionAddressType(SDP_Connection *connection);
+
+
+

This function retrieves the connection address type from an SDP_Connection struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the connection address type.

    +
  • Parameters
  • +
      +
    • connection
    • +

      The SDP_Connection struct to retrieve the connection address type from.

      +
    +
+

SDP_GetConnectionAddress(connection)

+ +
 const char *SDP_GetConnectionAddress(SDP_Connection *connection);
+
+
+

This function retrieves the connection address from an SDP_Connection struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the connection address.

    +
  • Parameters
  • +
      +
    • connection
    • +

      The SDP_Connection struct to retrieve the connection address from.

      +
    +
+

SDP_GetConnectionTTL(connection)

+ +
 int SDP_GetConnectionTTL(SDP_Connection *connection);
+
+
+

This function retrieves the connection tTL from an SDP_Connection struct.

+
    +
  • Return Value
  • +

    The connection tTL.

    +
  • Parameters
  • +
      +
    • connection
    • +

      The SDP_Connection struct to retrieve the connection tTL from.

      +
    +
+

SDP_GetTotalConnectionAddresses(connection)

+ +
 int SDP_GetTotalConnectionAddresses(SDP_Connection *connection);
+
+
+

This function retrieves the total connection addresses from an SDP_Connection struct.

+
    +
  • Return Value
  • +

    The total connection addresses.

    +
  • Parameters
  • +
      +
    • connection
    • +

      The SDP_Connection struct to retrieve the total connection addresses from.

      +
    +
+

SDP_GetBandwidth(description)

+ +
 SDP_Bandwidth *SDP_GetBandwidth(SDP_Description *description);
+
+
+

This function retrieves the bandwidth from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the bandwidth.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the bandwidth from.

      +
    +
+

SDP_GetBandwidthModifier(bandwidth)

+ +
 const char *SDP_GetBandwidthModifier(SDP_Bandwidth *bandwidth);
+
+
+

This function retrieves the bandwidth modifier from an SDP_Bandwidth struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the bandwidth modifier.

    +
  • Parameters
  • +
      +
    • bandwidth
    • +

      The SDP_Bandwidth struct to retrieve the bandwidth modifier from.

      +
    +
+

SDP_GetBandwidthValue(bandwidth)

+ +
 long SDP_GetBandwidthValue(SDP_Bandwidth *bandwidth);
+
+
+

This function retrieves the bandwidth value from an SDP_Bandwidth struct.

+
    +
  • Return Value
  • +

    The bandwidth value.

    +
  • Parameters
  • +
      +
    • bandwidth
    • +

      The SDP_Bandwidth struct to retrieve the bandwidth value from.

      +
    +
+

SDP_GetSessionPlayTimes(description)

+ +
 SDP_SessionPlayTime *SDP_GetSessionPlayTimes(
+ 	SDP_Description *description
+ );
+
+
+

This function retrieves the session play times from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the session play times.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the session play times from.

      +
    +
+

SDP_GetNextSessionPlayTime(session_play_time)

+ +
 #define SDP_GetNextSessionPlayTime SDP_GetNext
+
+
+

Gets the next SDP_SessionPlayTime struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the next SDP_SessionPlayTime struct in the linked list or NULL if there is none.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      A pointer to a SDP_SessionPlayTime struct.

      +
    +
+

SDP_GetPreviousSessionPlayTime(session_play_time)

+ +
 #define SDP_GetPreviousSessionPlayTime SDP_GetPrevious
+
+
+

Gets the previous SDP_SessionPlayTime struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the previous SDP_SessionPlayTime struct in the linked list, or NULL if there is none.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      A pointer to a SDP_SessionPlayTime struct.

      +
    +
+

SDP_GetStartTime(session_play_time)

+ +
 time_t SDP_GetStartTime(SDP_SessionPlayTime *session_play_time);
+
+
+

This function retrieves the start time from an SDP_SessionPlayTime struct.

+
    +
  • Return Value
  • +

    The start time.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      The SDP_SessionPlayTime struct to retrieve the start time from.

      +
    +
+

SDP_GetEndTime(session_play_time)

+ +
 time_t SDP_GetEndTime(SDP_SessionPlayTime *session_play_time);
+
+
+

This function retrieves the end time from an SDP_SessionPlayTime struct.

+
    +
  • Return Value
  • +

    The end time.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      The SDP_SessionPlayTime struct to retrieve the end time from.

      +
    +
+

SDP_GetRepeatTimes(session_play_time)

+ +
 SDP_RepeatTime *SDP_GetRepeatTimes(
+ 	SDP_SessionPlayTime *session_play_time
+ );
+
+
+

This function retrieves the repeat times from an SDP_SessionPlayTime struct.

+
    +
  • Return Value
  • +

    A pointer to the repeat times.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      The SDP_SessionPlayTime struct to retrieve the repeat times from.

      +
    +
+

SDP_GetNextRepeatTime(repeat_time)

+ +
 #define SDP_GetNextRepeatTime SDP_GetNext
+
+
+

Gets the next SDP_RepeatTime struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the next SDP_RepeatTime struct in the linked list or NULL if there is none.

    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      A pointer to a SDP_RepeatTime struct.

      +
    +
+

SDP_GetPreviousRepeatTime(repeat_time)

+ +
 #define SDP_GetPreviousRepeatTime SDP_GetPrevious
+
+
+

Gets the previous SDP_RepeatTime struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the previous SDP_RepeatTime struct in the linked list, or NULL if there is none.

    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      A pointer to a SDP_RepeatTime struct.

      +
    +
+

SDP_GetRepeatInterval(repeat_time)

+ +
 unsigned long SDP_GetRepeatInterval(SDP_RepeatTime *repeat_time);
+
+
+

This function retrieves the repeat interval from an SDP_RepeatTime struct.

+
    +
  • Return Value
  • +

    The repeat interval.

    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      The SDP_RepeatTime struct to retrieve the repeat interval from.

      +
    +
+

SDP_GetActiveDuration(repeat_time)

+ +
 unsigned long SDP_GetActiveDuration(SDP_RepeatTime *repeat_time);
+
+
+

This function retrieves the active duration from an SDP_RepeatTime struct.

+
    +
  • Return Value
  • +

    The active duration.

    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      The SDP_RepeatTime struct to retrieve the active duration from.

      +
    +
+

SDP_GetRepeatOffsets(repeat_time)

+ +
 unsigned long *SDP_GetRepeatOffsets(SDP_RepeatTime *repeat_time);
+
+
+

This function retrieves the repeat offsets from an SDP_RepeatTime struct.

+
    +
  • Return Value
  • +

    A pointer to the repeat offsets.

    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      The SDP_RepeatTime struct to retrieve the repeat offsets from.

      +
    +
+

SDP_GetTotalRepeatOffsets(repeat_time)

+ +
 int SDP_GetTotalRepeatOffsets(SDP_RepeatTime *repeat_time);
+
+
+

This function retrieves the total repeat offsets from an SDP_RepeatTime struct.

+
    +
  • Return Value
  • +

    The total repeat offsets.

    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      The SDP_RepeatTime struct to retrieve the total repeat offsets from.

      +
    +
+

SDP_RemoveRepeatTime(session_play_times, repeat_time)

+ +
 void SDP_RemoveRepeatTime(
+ 	SDP_SessionPlayTime *   session_play_times,
+ 	SDP_RepeatTime *        repeat_time
+ );
+
+
+

This removes (but does not destroy) the specified SDP_RepeatTime +struct from the repeat time list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • session_play_times
    • +

      A pointer to the SDP_SessionPlayTime struct containing the list.

      +
    • repeat_time
    • +

      A pointer to the SDP_RepeatTime you want removed from the list.

      +
    +
+

SDP_RemoveSessionPlayTime(description, session_play_time)

+ +
 void SDP_RemoveSessionPlayTime(
+ 	SDP_Description *       description,
+ 	SDP_SessionPlayTime *   session_play_time
+ );
+
+
+

This removes (but does not destroy) the specified SDP_SessionPlayTime +struct from the session play time list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the list.

      +
    • session_play_time
    • +

      A pointer to the SDP_SessionPlayTime you want removed from the list.

      +
    +
+

SDP_GetZoneAdjustments(description)

+ +
 SDP_ZoneAdjustment *SDP_GetZoneAdjustments(SDP_Description *description);
+
+
+

This function retrieves the zone adjustments from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the zone adjustments.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the zone adjustments from.

      +
    +
+

SDP_GetNextZoneAdjustment(zone_adjustment)

+ +
 #define SDP_GetNextZoneAdjustment SDP_GetNext
+
+
+

Gets the next SDP_ZoneAdjustment struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the next SDP_ZoneAdjustment struct in the linked list or NULL if there is none.

    +
  • Parameters
  • +
      +
    • zone_adjustment
    • +

      A pointer to a SDP_ZoneAdjustment struct.

      +
    +
+

SDP_GetPreviousZoneAdjustment(zone_adjustment)

+ +
 #define SDP_GetPreviousZoneAdjustment SDP_GetPrevious
+
+
+

Gets the previous SDP_ZoneAdjustment struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the previous SDP_ZoneAdjustment struct in the linked list, or NULL if there is none.

    +
  • Parameters
  • +
      +
    • zone_adjustment
    • +

      A pointer to a SDP_ZoneAdjustment struct.

      +
    +
+

SDP_GetZoneAdjustmentTime(zone_adjustment)

+ +
 time_t SDP_GetZoneAdjustmentTime(SDP_ZoneAdjustment *zone_adjustment);
+
+
+

This function retrieves the zone adjustment time from an SDP_ZoneAdjustment struct.

+
    +
  • Return Value
  • +

    The zone adjustment time.

    +
  • Parameters
  • +
      +
    • zone_adjustment
    • +

      The SDP_ZoneAdjustment struct to retrieve the zone adjustment time from.

      +
    +
+

SDP_GetZoneAdjustmentOffset(zone_adjustment)

+ +
 long SDP_GetZoneAdjustmentOffset(SDP_ZoneAdjustment *zone_adjustment);
+
+
+

This function retrieves the zone adjustment offset from an SDP_ZoneAdjustment struct.

+
    +
  • Return Value
  • +

    The zone adjustment offset.

    +
  • Parameters
  • +
      +
    • zone_adjustment
    • +

      The SDP_ZoneAdjustment struct to retrieve the zone adjustment offset from.

      +
    +
+

SDP_RemoveZoneAdjustment(description, zone_adjustment)

+ +
 void SDP_RemoveZoneAdjustment(
+ 	SDP_Description *      description,
+ 	SDP_ZoneAdjustment *   zone_adjustment
+ );
+
+
+

This removes (but does not destroy) the specified SDP_ZoneAdjustment +struct from the zone adjustment list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the list.

      +
    • zone_adjustment
    • +

      A pointer to the SDP_ZoneAdjustment you want removed from the list.

      +
    +
+

SDP_GetEncryption(description)

+ +
 SDP_Encryption *SDP_GetEncryption(SDP_Description *description);
+
+
+

This function retrieves the encryption from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the encryption.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the encryption from.

      +
    +
+

SDP_GetEncryptionMethod(encryption)

+ +
 const char *SDP_GetEncryptionMethod(SDP_Encryption *encryption);
+
+
+

This function retrieves the encryption method from an SDP_Encryption struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the encryption method.

    +
  • Parameters
  • +
      +
    • encryption
    • +

      The SDP_Encryption struct to retrieve the encryption method from.

      +
    +
+

SDP_GetEncryptionKey(encryption)

+ +
 const char *SDP_GetEncryptionKey(SDP_Encryption *encryption);
+
+
+

This function retrieves the encryption key from an SDP_Encryption struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the encryption key.

    +
  • Parameters
  • +
      +
    • encryption
    • +

      The SDP_Encryption struct to retrieve the encryption key from.

      +
    +
+

SDP_GetAttributes(description)

+ +
 SDP_Attribute *SDP_GetAttributes(SDP_Description *description);
+
+
+

This function retrieves the attributes from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the attributes.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the attributes from.

      +
    +
+

SDP_GetNextAttribute(attribute)

+ +
 #define SDP_GetNextAttribute SDP_GetNext
+
+
+

Gets the next SDP_Attribute struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the next SDP_Attribute struct in the linked list or NULL if there is none.

    +
  • Parameters
  • +
      +
    • attribute
    • +

      A pointer to a SDP_Attribute struct.

      +
    +
+

SDP_GetPreviousAttribute(attribute)

+ +
 #define SDP_GetPreviousAttribute SDP_GetPrevious
+
+
+

Gets the previous SDP_Attribute struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the previous SDP_Attribute struct in the linked list, or NULL if there is none.

    +
  • Parameters
  • +
      +
    • attribute
    • +

      A pointer to a SDP_Attribute struct.

      +
    +
+

SDP_GetAttributeName(attribute)

+ +
 const char *SDP_GetAttributeName(SDP_Attribute *attribute);
+
+
+

This function retrieves the attribute name from an SDP_Attribute struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the attribute name.

    +
  • Parameters
  • +
      +
    • attribute
    • +

      The SDP_Attribute struct to retrieve the attribute name from.

      +
    +
+

SDP_GetAttributeValue(attribute)

+ +
 const char *SDP_GetAttributeValue(SDP_Attribute *attribute);
+
+
+

This function retrieves the attribute value from an SDP_Attribute struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the attribute value.

    +
  • Parameters
  • +
      +
    • attribute
    • +

      The SDP_Attribute struct to retrieve the attribute value from.

      +
    +
+

SDP_RemoveAttribute(description, attribute)

+ +
 void SDP_RemoveAttribute(
+ 	SDP_Description *   description,
+ 	SDP_Attribute *     attribute
+ );
+
+
+

This removes (but does not destroy) the specified SDP_Attribute +struct from the attribute list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the list.

      +
    • attribute
    • +

      A pointer to the SDP_Attribute you want removed from the list.

      +
    +
+

SDP_GetMediaDescriptions(description)

+ +
 SDP_MediaDescription *SDP_GetMediaDescriptions(
+ 	SDP_Description *description
+ );
+
+
+

This function retrieves the media descriptions from an SDP_Description struct.

+
    +
  • Return Value
  • +

    A pointer to the media descriptions.

    +
  • Parameters
  • +
      +
    • description
    • +

      The SDP_Description struct to retrieve the media descriptions from.

      +
    +
+

SDP_GetNextMediaDescription(media_description)

+ +
 #define SDP_GetNextMediaDescription SDP_GetNext
+
+
+

Gets the next SDP_MediaDescription struct from the linked list.

+
    +
  • Return Value
  • +

    A pointer to the next SDP_MediaDescription struct in the linked list or NULL if there is none.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to a SDP_MediaDescription struct.

      +
    +
+

SDP_GetMediaType(media_description)

+ +
 const char *SDP_GetMediaType(SDP_MediaDescription *media_description);
+
+
+

This function retrieves the media type from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the media type.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the media type from.

      +
    +
+

SDP_GetMediaPort(media_description)

+ +
 unsigned short SDP_GetMediaPort(SDP_MediaDescription *media_description);
+
+
+

This function retrieves the media port from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    The media port.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the media port from.

      +
    +
+

SDP_GetTotalMediaPorts(media_description)

+ +
 unsigned short SDP_GetTotalMediaPorts(
+ 	SDP_MediaDescription *media_description
+ );
+
+
+

This function retrieves the total media ports from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    The total media ports.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the total media ports from.

      +
    +
+

SDP_GetMediaTransportProtocol(media_description)

+ +
 const char *SDP_GetMediaTransportProtocol(
+ 	SDP_MediaDescription *media_description
+ );
+
+
+

This function retrieves the media transport protocol from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the media transport protocol.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the media transport protocol from.

      +
    +
+

SDP_GetMediaFormats(media_description)

+ +
 const char *SDP_GetMediaFormats(SDP_MediaDescription *media_description);
+
+
+

This function retrieves the media formats from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the media formats.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the media formats from.

      +
    +
+

SDP_GetMediaInformation(media_description)

+ +
 const char *SDP_GetMediaInformation(
+ 	SDP_MediaDescription *media_description
+ );
+
+
+

This function retrieves the media information from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    A pointer to the string containing the media information.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the media information from.

      +
    +
+

SDP_GetMediaConnection(media_description)

+ +
 SDP_Connection *SDP_GetMediaConnection(
+ 	SDP_MediaDescription *media_description
+ );
+
+
+

This function retrieves the media connection from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    A pointer to the media connection.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the media connection from.

      +
    +
+

SDP_GetMediaBandwidth(media_description)

+ +
 SDP_Bandwidth *SDP_GetMediaBandwidth(
+ 	SDP_MediaDescription *media_description
+ );
+
+
+

This function retrieves the media bandwidth from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    A pointer to the media bandwidth.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the media bandwidth from.

      +
    +
+

SDP_GetMediaEncryption(media_description)

+ +
 SDP_Encryption *SDP_GetMediaEncryption(
+ 	SDP_MediaDescription *media_description
+ );
+
+
+

This function retrieves the media encryption from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    A pointer to the media encryption.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the media encryption from.

      +
    +
+

SDP_GetMediaAttributes(media_description)

+ +
 SDP_Attribute *SDP_GetMediaAttributes(
+ 	SDP_MediaDescription *media_description
+ );
+
+
+

This function retrieves the media attributes from an SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    A pointer to the media attributes.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      The SDP_MediaDescription struct to retrieve the media attributes from.

      +
    +
+

SDP_RemoveMediaDescription(description, media_description)

+ +
 void SDP_RemoveMediaDescription(
+ 	SDP_Description *        description,
+ 	SDP_MediaDescription *   media_description
+ );
+
+
+

This removes (but does not destroy) the specified SDP_MediaDescription +struct from the media description list.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct containing the list.

      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription you want removed from the list.

      +
    +
+

DESTRUCTOR FUNCTIONS

+ +

These functions destroy dynamically allocated structures.

+

SDP_DestroyDescriptions(descriptions)

+ +
 void SDP_DestroyDescriptions(SDP_Description *descriptions);
+
+
+

This function destroys a descriptions linked list from an +SDP_Description struct, releasing its memory back to the operating system. +Do not try to use any items from the descriptions linked list after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • descriptions
    • +

      A pointer to the SDP_Description struct to destroy the descriptions from.

      +
    +
+

SDP_DestroyDescription(description)

+ +
 void SDP_DestroyDescription(SDP_Description *description);
+
+
+

This function destroys a SDP_Description struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct to destroy.

      +
    +
+

SDP_DestroyOwner(owner)

+ +
 void SDP_DestroyOwner(SDP_Owner *owner);
+
+
+

This function destroys a SDP_Owner struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • owner
    • +

      A pointer to the SDP_Owner struct to destroy.

      +
    +
+

SDP_DestroyEmailContacts(description)

+ +
 void SDP_DestroyEmailContacts(SDP_Description *description);
+
+
+

This function destroys a email contacts linked list from an +SDP_Description struct, releasing its memory back to the operating system. +Do not try to use any items from the email contacts linked list after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct to destroy the email contacts from.

      +
    +
+

SDP_DestroyEmailContact(email_contact)

+ +
 void SDP_DestroyEmailContact(SDP_EmailContact *email_contact);
+
+
+

This function destroys a SDP_EmailContact struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • email_contact
    • +

      A pointer to the SDP_EmailContact struct to destroy.

      +
    +
+

SDP_DestroyPhoneContacts(description)

+ +
 void SDP_DestroyPhoneContacts(SDP_Description *description);
+
+
+

This function destroys a phone contacts linked list from an +SDP_Description struct, releasing its memory back to the operating system. +Do not try to use any items from the phone contacts linked list after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct to destroy the phone contacts from.

      +
    +
+

SDP_DestroyPhoneContact(phone_contact)

+ +
 void SDP_DestroyPhoneContact(SDP_PhoneContact *phone_contact);
+
+
+

This function destroys a SDP_PhoneContact struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • phone_contact
    • +

      A pointer to the SDP_PhoneContact struct to destroy.

      +
    +
+

SDP_DestroyConnection(connection)

+ +
 void SDP_DestroyConnection(SDP_Connection *connection);
+
+
+

This function destroys a SDP_Connection struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • connection
    • +

      A pointer to the SDP_Connection struct to destroy.

      +
    +
+

SDP_DestroyBandwidth(bandwidth)

+ +
 void SDP_DestroyBandwidth(SDP_Bandwidth *bandwidth);
+
+
+

This function destroys a SDP_Bandwidth struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • bandwidth
    • +

      A pointer to the SDP_Bandwidth struct to destroy.

      +
    +
+

SDP_DestroySessionPlayTimes(description)

+ +
 void SDP_DestroySessionPlayTimes(SDP_Description *description);
+
+
+

This function destroys a session play times linked list from an +SDP_Description struct, releasing its memory back to the operating system. +Do not try to use any items from the session play times linked list after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct to destroy the session play times from.

      +
    +
+

SDP_DestroySessionPlayTime(session_play_time)

+ +
 void SDP_DestroySessionPlayTime(SDP_SessionPlayTime *session_play_time);
+
+
+

This function destroys a SDP_SessionPlayTime struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      A pointer to the SDP_SessionPlayTime struct to destroy.

      +
    +
+

SDP_DestroyRepeatTimes(session_play_time)

+ +
 void SDP_DestroyRepeatTimes(SDP_SessionPlayTime *session_play_time);
+
+
+

This function destroys a repeat times linked list from an +SDP_SessionPlayTime struct, releasing its memory back to the operating system. +Do not try to use any items from the repeat times linked list after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • session_play_time
    • +

      A pointer to the SDP_SessionPlayTime struct to destroy the repeat times from.

      +
    +
+

SDP_DestroyRepeatTime(repeat_time)

+ +
 void SDP_DestroyRepeatTime(SDP_RepeatTime *repeat_time);
+
+
+

This function destroys a SDP_RepeatTime struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • repeat_time
    • +

      A pointer to the SDP_RepeatTime struct to destroy.

      +
    +
+

SDP_DestroyZoneAdjustments(description)

+ +
 void SDP_DestroyZoneAdjustments(SDP_Description *description);
+
+
+

This function destroys a zone adjustments linked list from an +SDP_Description struct, releasing its memory back to the operating system. +Do not try to use any items from the zone adjustments linked list after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct to destroy the zone adjustments from.

      +
    +
+

SDP_DestroyZoneAdjustment(zone_adjustment)

+ +
 void SDP_DestroyZoneAdjustment(SDP_ZoneAdjustment *zone_adjustment);
+
+
+

This function destroys a SDP_ZoneAdjustment struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • zone_adjustment
    • +

      A pointer to the SDP_ZoneAdjustment struct to destroy.

      +
    +
+

SDP_DestroyEncryption(encryption)

+ +
 void SDP_DestroyEncryption(SDP_Encryption *encryption);
+
+
+

This function destroys a SDP_Encryption struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • encryption
    • +

      A pointer to the SDP_Encryption struct to destroy.

      +
    +
+

SDP_DestroyAttributes(description)

+ +
 void SDP_DestroyAttributes(SDP_Description *description);
+
+
+

This function destroys an attributes linked list from an +SDP_Description struct, releasing its memory back to the operating system. +Do not try to use any items from the attributes linked list after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct to destroy the attributes from.

      +
    +
+

SDP_DestroyAttribute(attribute)

+ +
 void SDP_DestroyAttribute(SDP_Attribute *attribute);
+
+
+

This function destroys a SDP_Attribute struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • attribute
    • +

      A pointer to the SDP_Attribute struct to destroy.

      +
    +
+

SDP_DestroyMediaDescriptions(description)

+ +
 void SDP_DestroyMediaDescriptions(SDP_Description *description);
+
+
+

This function destroys a media descriptions linked list from an +SDP_Description struct, releasing its memory back to the operating system. +Do not try to use any items from the media descriptions linked list after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to the SDP_Description struct to destroy the media descriptions from.

      +
    +
+

SDP_DestroyMediaDescription(media_description)

+ +
 void SDP_DestroyMediaDescription(SDP_MediaDescription *media_description);
+
+
+

This function destroys a SDP_MediaDescription struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct to destroy.

      +
    +
+

SDP_DestroyMediaAttributes(media_description)

+ +
 void SDP_DestroyMediaAttributes(SDP_MediaDescription *media_description);
+
+
+

This function destroys a media attributes linked list from an +SDP_MediaDescription struct, releasing its memory back to the operating system. +Do not try to use any items from the media attributes linked list after destroying it.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • media_description
    • +

      A pointer to the SDP_MediaDescription struct to destroy the media attributes from.

      +
    +
+

BUGS

+ +

Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse

+

You can also email me directly: +<william_g_davis at users dot sourceforge dot net>.

+

COPYRIGHT

+ +

Copyright 2004 by William G. Davis.

+

This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution.

+

This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE.

+ + +
diff --git a/src/sdp_lib/SinisterSdpDescriptions.pod b/src/sdp_lib/SinisterSdpDescriptions.pod new file mode 100644 index 0000000..4e335de --- /dev/null +++ b/src/sdp_lib/SinisterSdpDescriptions.pod @@ -0,0 +1,5091 @@ +=head1 NAME + +SinisterSdpDescriptions - Routines to manipulate descriptions. + +=head1 SYNOPSIS + + #include + + int main(void) + { + SDP_Description *description = SDP_NewDescription(); + SDP_SetProtocolVersion(description, 1); + SDP_SetSessionName(description, "Session Name"); + ... + } + +=head1 DESCRIPTION + +This document describes how to use C structs. + +These structs are returned by the SinisterSdp parser functions and manpulated +using a series of Get/Set, Add/Remove, and New/Destroy routines. +You'll probably only end up using the Get routines and maybe a few of the Set +routines, but the others are always there if you need them. + +The functions that return "const char *" return pointers to internal string +buffers. If you need to modify them, then use strdup() or something similar to +copy them, then modify the copy. + +=head1 FUNCTIONS + +The following routines are available: + +=head1 CONSTRUCTOR FUNCTIONS + +These functions create and return new structs to encapsulate some portion of an +SDP description. + +=head2 SDP_NewDescription() + + SDP_Description *SDP_NewDescription(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_Description struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewOwner() + + SDP_Owner *SDP_NewOwner(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_Owner struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewEmailContact() + + SDP_EmailContact *SDP_NewEmailContact(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_EmailContact struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewPhoneContact() + + SDP_PhoneContact *SDP_NewPhoneContact(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_PhoneContact struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewConnection() + + SDP_Connection *SDP_NewConnection(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_Connection struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewBandwidth() + + SDP_Bandwidth *SDP_NewBandwidth(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_Bandwidth struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewSessionPlayTime() + + SDP_SessionPlayTime *SDP_NewSessionPlayTime(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_SessionPlayTime struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewRepeatTime() + + SDP_RepeatTime *SDP_NewRepeatTime(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_RepeatTime struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewZoneAdjustment() + + SDP_ZoneAdjustment *SDP_NewZoneAdjustment(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_ZoneAdjustment struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewEncryption() + + SDP_Encryption *SDP_NewEncryption(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_Encryption struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewAttribute() + + SDP_Attribute *SDP_NewAttribute(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_Attribute struct. + +=item Parameters + +None. + +=back + +=head2 SDP_NewMediaDescription() + + SDP_MediaDescription *SDP_NewMediaDescription(void); + +This function creates a new C struct. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_MediaDescription struct. + +=item Parameters + +None. + +=back + +=head1 "SET" ACCESSOR FUNCTIONS + +These functions enable you to set values within structs that encapsulates +portions of an SDP description. + +=head2 SDP_SetProtocolVersion(description, version) + + void SDP_SetProtocolVersion( + SDP_Description * description, + int version + ); + +This function sets the protocol version within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct. + +=item version + +The version. + +=back + +=back + +=head2 SDP_SetOwner(description, username, session_id, session_version, network_type, address_type, address) + + int SDP_SetOwner( + SDP_Description * description, + const char * username, + const char * session_id, + const char * session_version, + const char * network_type, + const char * address_type, + const char * address + ); + +This function sets the owner within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the owner. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct. + +=item username + +A pointer to a string containing the username. + +=item session_id + +A pointer to a string containing the session id. + +=item session_version + +A pointer to a string containing the session version. + +=item network_type + +A pointer to a string containing the network type. + +=item address_type + +A pointer to a string containing the address type. + +=item address + +A pointer to a string containing the address. + +=back + +=back + +=head2 SDP_SetUsername(owner, username) + + int SDP_SetUsername( + SDP_Owner * owner, + const char * username + ); + +This function sets the username within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the username. + +=item Parameters + +=over 4 + +=item owner + +A pointer to the C struct. + +=item username + +A pointer to a string containing the username. + +=back + +=back + +=head2 SDP_SetSessionID(owner, session_id) + + int SDP_SetSessionID( + SDP_Owner * owner, + const char * session_id + ); + +This function sets the session iD within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the session iD. + +=item Parameters + +=over 4 + +=item owner + +A pointer to the C struct. + +=item session_id + +A pointer to a string containing the session id. + +=back + +=back + +=head2 SDP_SetSessionVersion(owner, session_version) + + int SDP_SetSessionVersion( + SDP_Owner * owner, + const char * session_version + ); + +This function sets the session version within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the session version. + +=item Parameters + +=over 4 + +=item owner + +A pointer to the C struct. + +=item session_version + +A pointer to a string containing the session version. + +=back + +=back + +=head2 SDP_SetOwnerNetworkType(owner, network_type) + + int SDP_SetOwnerNetworkType( + SDP_Owner * owner, + const char * network_type + ); + +This function sets the owner network type within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the owner network type. + +=item Parameters + +=over 4 + +=item owner + +A pointer to the C struct. + +=item network_type + +A pointer to a string containing the network type. + +=back + +=back + +=head2 SDP_SetOwnerAddressType(owner, address_type) + + int SDP_SetOwnerAddressType( + SDP_Owner * owner, + const char * address_type + ); + +This function sets the owner address type within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the owner address type. + +=item Parameters + +=over 4 + +=item owner + +A pointer to the C struct. + +=item address_type + +A pointer to a string containing the address type. + +=back + +=back + +=head2 SDP_SetOwnerAddress(owner, address) + + int SDP_SetOwnerAddress( + SDP_Owner * owner, + const char * address + ); + +This function sets the owner address within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the owner address. + +=item Parameters + +=over 4 + +=item owner + +A pointer to the C struct. + +=item address + +A pointer to a string containing the address. + +=back + +=back + +=head2 SDP_SetSessionName(description, session_name) + + int SDP_SetSessionName( + SDP_Description * description, + const char * session_name + ); + +This function sets the session name within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the session name. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct. + +=item session_name + +A pointer to a string containing the session name. + +=back + +=back + +=head2 SDP_SetSessionInformation(description, session_information) + + int SDP_SetSessionInformation( + SDP_Description * description, + const char * session_information + ); + +This function sets the session information within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the session information. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct. + +=item session_information + +A pointer to a string containing the session information. + +=back + +=back + +=head2 SDP_SetURI(description, uri) + + int SDP_SetURI( + SDP_Description * description, + const char * uri + ); + +This function sets the URI within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the URI. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct. + +=item uri + +A pointer to a string containing the uri. + +=back + +=back + +=head2 SDP_AddEmailContact(description, email_contact) + + void SDP_AddEmailContact( + SDP_Description * description, + SDP_EmailContact * email_contact + ); + +This function adds an C struct to the email contact +linked list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the email contact linked list. + +=item email_contact + +A pointer to the C struct to add. + +=back + +=back + +=head2 SDP_AddNewEmailContact(description, address, name) + + int SDP_AddNewEmailContact( + SDP_Description * description, + const char * address, + const char * name + ); + +This function creates and adds a new email contact to the +email contact linked list. + +=over 4 + +=item Return Value + +If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call C. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to create and add the email contact. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the email contact linked list. + +=item address + +A pointer to a string containing the address. + +=item name + +A pointer to a string containing the name. + +=back + +=back + +=head2 SDP_SetEmailAddress(email_contact, address) + + int SDP_SetEmailAddress( + SDP_EmailContact * email_contact, + const char * address + ); + +This function sets the email address within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the email address. + +=item Parameters + +=over 4 + +=item email_contact + +A pointer to the C struct. + +=item address + +A pointer to a string containing the address. + +=back + +=back + +=head2 SDP_SetEmailName(email_contact, name) + + int SDP_SetEmailName( + SDP_EmailContact * email_contact, + const char * name + ); + +This function sets the email name within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the email name. + +=item Parameters + +=over 4 + +=item email_contact + +A pointer to the C struct. + +=item name + +A pointer to a string containing the name. + +=back + +=back + +=head2 SDP_AddPhoneContact(description, phone_contact) + + void SDP_AddPhoneContact( + SDP_Description * description, + SDP_PhoneContact * phone_contact + ); + +This function adds an C struct to the phone contact +linked list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the phone contact linked list. + +=item phone_contact + +A pointer to the C struct to add. + +=back + +=back + +=head2 SDP_AddNewPhoneContact(description, number, name) + + int SDP_AddNewPhoneContact( + SDP_Description * description, + const char * number, + const char * name + ); + +This function creates and adds a new phone contact to the +phone contact linked list. + +=over 4 + +=item Return Value + +If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call C. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to create and add the phone contact. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the phone contact linked list. + +=item number + +A pointer to a string containing the number. + +=item name + +A pointer to a string containing the name. + +=back + +=back + +=head2 SDP_SetPhoneNumber(phone_contact, number) + + int SDP_SetPhoneNumber( + SDP_PhoneContact * phone_contact, + const char * number + ); + +This function sets the phone number within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the phone number. + +=item Parameters + +=over 4 + +=item phone_contact + +A pointer to the C struct. + +=item number + +A pointer to a string containing the number. + +=back + +=back + +=head2 SDP_SetPhoneName(phone_contact, name) + + int SDP_SetPhoneName( + SDP_PhoneContact * phone_contact, + const char * name + ); + +This function sets the phone name within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the phone name. + +=item Parameters + +=over 4 + +=item phone_contact + +A pointer to the C struct. + +=item name + +A pointer to a string containing the name. + +=back + +=back + +=head2 SDP_SetConnection(description, network_type, address_type, address, ttl, total_addresses) + + int SDP_SetConnection( + SDP_Description * description, + const char * network_type, + const char * address_type, + const char * address, + int ttl, + int total_addresses + ); + +This function sets the connection within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the connection. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct. + +=item network_type + +A pointer to a string containing the network type. + +=item address_type + +A pointer to a string containing the address type. + +=item address + +A pointer to a string containing the address. + +=item ttl + +The ttl. + +=item total_addresses + +The total addresses. + +=back + +=back + +=head2 SDP_SetConnectionNetworkType(connection, network_type) + + int SDP_SetConnectionNetworkType( + SDP_Connection * connection, + const char * network_type + ); + +This function sets the connection network type within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the connection network type. + +=item Parameters + +=over 4 + +=item connection + +A pointer to the C struct. + +=item network_type + +A pointer to a string containing the network type. + +=back + +=back + +=head2 SDP_SetConnectionAddressType(connection, address_type) + + int SDP_SetConnectionAddressType( + SDP_Connection * connection, + const char * address_type + ); + +This function sets the connection address type within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the connection address type. + +=item Parameters + +=over 4 + +=item connection + +A pointer to the C struct. + +=item address_type + +A pointer to a string containing the address type. + +=back + +=back + +=head2 SDP_SetConnectionAddress(connection, address) + + int SDP_SetConnectionAddress( + SDP_Connection * connection, + const char * address + ); + +This function sets the connection address within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the connection address. + +=item Parameters + +=over 4 + +=item connection + +A pointer to the C struct. + +=item address + +A pointer to a string containing the address. + +=back + +=back + +=head2 SDP_SetConnectionTTL(connection, ttl) + + void SDP_SetConnectionTTL( + SDP_Connection * connection, + int ttl + ); + +This function sets the connection tTL within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item connection + +A pointer to the C struct. + +=item ttl + +The ttl. + +=back + +=back + +=head2 SDP_SetTotalConnectionAddresses(connection, total_addresses) + + void SDP_SetTotalConnectionAddresses( + SDP_Connection * connection, + int total_addresses + ); + +This function sets the total connection addresses within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item connection + +A pointer to the C struct. + +=item total_addresses + +The total addresses. + +=back + +=back + +=head2 SDP_SetBandwidth(description, modifier, value) + + int SDP_SetBandwidth( + SDP_Description * description, + const char * modifier, + long value + ); + +This function sets the bandwidth within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the bandwidth. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct. + +=item modifier + +A pointer to a string containing the modifier. + +=item value + +The value. + +=back + +=back + +=head2 SDP_SetBandwidthModifier(bandwidth, modifier) + + int SDP_SetBandwidthModifier( + SDP_Bandwidth * bandwidth, + const char * modifier + ); + +This function sets the bandwidth modifier within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the bandwidth modifier. + +=item Parameters + +=over 4 + +=item bandwidth + +A pointer to the C struct. + +=item modifier + +A pointer to a string containing the modifier. + +=back + +=back + +=head2 SDP_SetBandwidthValue(bandwidth, value) + + void SDP_SetBandwidthValue( + SDP_Bandwidth * bandwidth, + long value + ); + +This function sets the bandwidth value within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item bandwidth + +A pointer to the C struct. + +=item value + +The value. + +=back + +=back + +=head2 SDP_AddSessionPlayTime(description, session_play_time) + + void SDP_AddSessionPlayTime( + SDP_Description * description, + SDP_SessionPlayTime * session_play_time + ); + +This function adds an C struct to the session play time +linked list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the session play time linked list. + +=item session_play_time + +A pointer to the C struct to add. + +=back + +=back + +=head2 SDP_AddNewSessionPlayTime(description, start_time, end_time) + + int SDP_AddNewSessionPlayTime( + SDP_Description * description, + time_t start_time, + time_t end_time + ); + +This function creates and adds a new session play time to the +session play time linked list. + +=over 4 + +=item Return Value + +If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call C. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to create and add the session play time. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the session play time linked list. + +=item start_time + +The start time. + +=item end_time + +The end time. + +=back + +=back + +=head2 SDP_SetStartTime(session_play_time, start_time) + + void SDP_SetStartTime( + SDP_SessionPlayTime * session_play_time, + time_t start_time + ); + +This function sets the start time within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item session_play_time + +A pointer to the C struct. + +=item start_time + +The start time. + +=back + +=back + +=head2 SDP_SetEndTime(session_play_time, end_time) + + void SDP_SetEndTime( + SDP_SessionPlayTime * session_play_time, + time_t end_time + ); + +This function sets the end time within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item session_play_time + +A pointer to the C struct. + +=item end_time + +The end time. + +=back + +=back + +=head2 SDP_AddRepeatTime(session_play_time, repeat_time) + + void SDP_AddRepeatTime( + SDP_SessionPlayTime * session_play_time, + SDP_RepeatTime * repeat_time + ); + +This function adds an C struct to the repeat time +linked list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item session_play_time + +A pointer to the C struct containing the repeat time linked list. + +=item repeat_time + +A pointer to the C struct to add. + +=back + +=back + +=head2 SDP_AddNewRepeatTime(session_play_time, repeat_interval, active_duration, repeat_offsets, total_offsets) + + int SDP_AddNewRepeatTime( + SDP_SessionPlayTime * session_play_time, + unsigned long repeat_interval, + unsigned long active_duration, + const unsigned long repeat_offsets[], + int total_offsets + ); + +This function creates and adds a new repeat time to the +repeat time linked list. + +=over 4 + +=item Return Value + +If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call C. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to create and add the repeat time. + +=item Parameters + +=over 4 + +=item session_play_time + +A pointer to the C struct containing the repeat time linked list. + +=item repeat_interval + +The repeat interval. + +=item active_duration + +The active duration. + +=item repeat_offsets + +The repeat offsets. + +=item total_offsets + +The total offsets. + +=back + +=back + +=head2 SDP_SetRepeatInterval(repeat_time, repeat_interval) + + void SDP_SetRepeatInterval( + SDP_RepeatTime * repeat_time, + unsigned long repeat_interval + ); + +This function sets the repeat interval within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item repeat_time + +A pointer to the C struct. + +=item repeat_interval + +The repeat interval. + +=back + +=back + +=head2 SDP_SetActiveDuration(repeat_time, active_duration) + + void SDP_SetActiveDuration( + SDP_RepeatTime * repeat_time, + unsigned long active_duration + ); + +This function sets the active duration within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item repeat_time + +A pointer to the C struct. + +=item active_duration + +The active duration. + +=back + +=back + +=head2 SDP_SetRepeatOffsets(repeat_time, repeat_offsets, total_offsets) + + int SDP_SetRepeatOffsets( + SDP_RepeatTime * repeat_time, + const unsigned long repeat_offsets[], + int total_offsets + ); + +This function sets the repeat offsets within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the repeat offsets. + +=item Parameters + +=over 4 + +=item repeat_time + +A pointer to the C struct. + +=item repeat_offsets + +The repeat offsets. + +=item total_offsets + +The total offsets. + +=back + +=back + +=head2 SDP_AddZoneAdjustment(description, zone_adjustment) + + void SDP_AddZoneAdjustment( + SDP_Description * description, + SDP_ZoneAdjustment * zone_adjustment + ); + +This function adds an C struct to the zone adjustment +linked list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the zone adjustment linked list. + +=item zone_adjustment + +A pointer to the C struct to add. + +=back + +=back + +=head2 SDP_AddNewZoneAdjustment(description, time, offset) + + int SDP_AddNewZoneAdjustment( + SDP_Description * description, + time_t time, + long offset + ); + +This function creates and adds a new zone adjustment to the +zone adjustment linked list. + +=over 4 + +=item Return Value + +If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call C. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to create and add the zone adjustment. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the zone adjustment linked list. + +=item time + +The time. + +=item offset + +The offset. + +=back + +=back + +=head2 SDP_SetZoneAdjustmentTime(zone_adjustment, time) + + void SDP_SetZoneAdjustmentTime( + SDP_ZoneAdjustment * zone_adjustment, + time_t time + ); + +This function sets the zone adjustment time within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item zone_adjustment + +A pointer to the C struct. + +=item time + +The time. + +=back + +=back + +=head2 SDP_SetZoneAdjustmentOffset(zone_adjustment, offset) + + void SDP_SetZoneAdjustmentOffset( + SDP_ZoneAdjustment * zone_adjustment, + long offset + ); + +This function sets the zone adjustment offset within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item zone_adjustment + +A pointer to the C struct. + +=item offset + +The offset. + +=back + +=back + +=head2 SDP_SetEncryption(description, method, key) + + int SDP_SetEncryption( + SDP_Description * description, + const char * method, + const char * key + ); + +This function sets the encryption within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the encryption. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct. + +=item method + +A pointer to a string containing the method. + +=item key + +A pointer to a string containing the key. + +=back + +=back + +=head2 SDP_SetEncryptionMethod(encryption, method) + + int SDP_SetEncryptionMethod( + SDP_Encryption * encryption, + const char * method + ); + +This function sets the encryption method within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the encryption method. + +=item Parameters + +=over 4 + +=item encryption + +A pointer to the C struct. + +=item method + +A pointer to a string containing the method. + +=back + +=back + +=head2 SDP_SetEncryptionKey(encryption, key) + + int SDP_SetEncryptionKey( + SDP_Encryption * encryption, + const char * key + ); + +This function sets the encryption key within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the encryption key. + +=item Parameters + +=over 4 + +=item encryption + +A pointer to the C struct. + +=item key + +A pointer to a string containing the key. + +=back + +=back + +=head2 SDP_AddAttribute(description, attribute) + + void SDP_AddAttribute( + SDP_Description * description, + SDP_Attribute * attribute + ); + +This function adds an C struct to the attribute +linked list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the attribute linked list. + +=item attribute + +A pointer to the C struct to add. + +=back + +=back + +=head2 SDP_AddNewAttribute(description, name, value) + + int SDP_AddNewAttribute( + SDP_Description * description, + const char * name, + const char * value + ); + +This function creates and adds a new attribute to the +attribute linked list. + +=over 4 + +=item Return Value + +If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call C. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to create and add the attribute. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the attribute linked list. + +=item name + +A pointer to a string containing the name. + +=item value + +A pointer to a string containing the value. + +=back + +=back + +=head2 SDP_SetAttributeName(attribute, name) + + int SDP_SetAttributeName( + SDP_Attribute * attribute, + const char * name + ); + +This function sets the attribute name within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the attribute name. + +=item Parameters + +=over 4 + +=item attribute + +A pointer to the C struct. + +=item name + +A pointer to a string containing the name. + +=back + +=back + +=head2 SDP_SetAttributeValue(attribute, value) + + int SDP_SetAttributeValue( + SDP_Attribute * attribute, + const char * value + ); + +This function sets the attribute value within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the attribute value. + +=item Parameters + +=over 4 + +=item attribute + +A pointer to the C struct. + +=item value + +A pointer to a string containing the value. + +=back + +=back + +=head2 SDP_AddMediaDescription(description, media_description) + + void SDP_AddMediaDescription( + SDP_Description * description, + SDP_MediaDescription * media_description + ); + +This function adds an C struct to the media description +linked list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the media description linked list. + +=item media_description + +A pointer to the C struct to add. + +=back + +=back + +=head2 SDP_AddNewMediaDescription(description, media_type, port, total_ports, transport_protocol, formats, media_information) + + int SDP_AddNewMediaDescription( + SDP_Description * description, + const char * media_type, + unsigned short port, + unsigned short total_ports, + const char * transport_protocol, + const char * formats, + const char * media_information + ); + +This function creates and adds a new media description to the +media description linked list. + +=over 4 + +=item Return Value + +If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call C. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to create and add the media description. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the media description linked list. + +=item media_type + +A pointer to a string containing the media type. + +=item port + +The port. + +=item total_ports + +The total ports. + +=item transport_protocol + +A pointer to a string containing the transport protocol. + +=item formats + +A pointer to a string containing the formats. + +=item media_information + +A pointer to a string containing the media information. + +=back + +=back + +=head2 SDP_SetMediaType(media_description, media_type) + + int SDP_SetMediaType( + SDP_MediaDescription * media_description, + const char * media_type + ); + +This function sets the media type within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the media type. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct. + +=item media_type + +A pointer to a string containing the media type. + +=back + +=back + +=head2 SDP_SetMediaPort(media_description, port) + + void SDP_SetMediaPort( + SDP_MediaDescription * media_description, + unsigned short port + ); + +This function sets the media port within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct. + +=item port + +The port. + +=back + +=back + +=head2 SDP_SetTotalMediaPorts(media_description, total_ports) + + void SDP_SetTotalMediaPorts( + SDP_MediaDescription * media_description, + unsigned short total_ports + ); + +This function sets the total media ports within an C +struct. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct. + +=item total_ports + +The total ports. + +=back + +=back + +=head2 SDP_SetMediaTransportProtocol(media_description, transport_protocol) + + int SDP_SetMediaTransportProtocol( + SDP_MediaDescription * media_description, + const char * transport_protocol + ); + +This function sets the media transport protocol within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the media transport protocol. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct. + +=item transport_protocol + +A pointer to a string containing the transport protocol. + +=back + +=back + +=head2 SDP_SetMediaFormats(media_description, formats) + + int SDP_SetMediaFormats( + SDP_MediaDescription * media_description, + const char * formats + ); + +This function sets the media formats within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the media formats. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct. + +=item formats + +A pointer to a string containing the formats. + +=back + +=back + +=head2 SDP_SetMediaInformation(media_description, media_information) + + int SDP_SetMediaInformation( + SDP_MediaDescription * media_description, + const char * media_information + ); + +This function sets the media information within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the media information. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct. + +=item media_information + +A pointer to a string containing the media information. + +=back + +=back + +=head2 SDP_SetMediaConnection(media_description, network_type, address_type, address, ttl, total_addresses) + + int SDP_SetMediaConnection( + SDP_MediaDescription * media_description, + const char * network_type, + const char * address_type, + const char * address, + int ttl, + int total_addresses + ); + +This function sets the media connection within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the media connection. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct. + +=item network_type + +A pointer to a string containing the network type. + +=item address_type + +A pointer to a string containing the address type. + +=item address + +A pointer to a string containing the address. + +=item ttl + +The ttl. + +=item total_addresses + +The total addresses. + +=back + +=back + +=head2 SDP_SetMediaBandwidth(media_description, modifier, value) + + int SDP_SetMediaBandwidth( + SDP_MediaDescription * media_description, + const char * modifier, + long value + ); + +This function sets the media bandwidth within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the media bandwidth. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct. + +=item modifier + +A pointer to a string containing the modifier. + +=item value + +The value. + +=back + +=back + +=head2 SDP_SetMediaEncryption(media_description, method, key) + + int SDP_SetMediaEncryption( + SDP_MediaDescription * media_description, + const char * method, + const char * key + ); + +This function sets the media encryption within an C +struct. + +=over 4 + +=item Return Value + +It returns true if no error occurs, false otherwise. For extended error +information call C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to set the media encryption. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct. + +=item method + +A pointer to a string containing the method. + +=item key + +A pointer to a string containing the key. + +=back + +=back + +=head2 SDP_AddMediaAttribute(media_description, attribute) + + void SDP_AddMediaAttribute( + SDP_MediaDescription * media_description, + SDP_Attribute * attribute + ); + +This function adds an C struct to the media attribute +linked list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct containing the media attribute linked list. + +=item attribute + +A pointer to the C struct to add. + +=back + +=back + +=head2 SDP_AddNewMediaAttribute(media_description, name, value) + + int SDP_AddNewMediaAttribute( + SDP_MediaDescription * media_description, + const char * name, + const char * value + ); + +This function creates and adds a new media attribute to the +media attribute linked list. + +=over 4 + +=item Return Value + +If no error occurs, it returns true. If an error occurs, it returns false. For +extended error information call C. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + to create and add the media attribute. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct containing the media attribute linked list. + +=item name + +A pointer to a string containing the name. + +=item value + +A pointer to a string containing the value. + +=back + +=back + +=head1 "GET" ACCESSOR FUNCTIONS + +These functions enable you to retrieve values from structs that encapsulates +portions of an SDP description. + +=head2 SDP_GetNextDescription(description) + + #define SDP_GetNextDescription SDP_GetNext + +Gets the next C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the next C struct in the linked list or NULL if there is none. + +=item Parameters + +=over 4 + +=item description + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetPreviousDescription(description) + + #define SDP_GetPreviousDescription SDP_GetPrevious + +Gets the previous C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the previous C struct in the linked list, or NULL if there is none. + +=item Parameters + +=over 4 + +=item description + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetProtocolVersion(description) + + int SDP_GetProtocolVersion(SDP_Description *description); + +This function retrieves the protocol version from an C struct. + +=over 4 + +=item Return Value + +The protocol version. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the protocol version from. + +=back + +=back + +=head2 SDP_GetOwner(description) + + SDP_Owner *SDP_GetOwner(SDP_Description *description); + +This function retrieves the owner from an C struct. + +=over 4 + +=item Return Value + +A pointer to the owner. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the owner from. + +=back + +=back + +=head2 SDP_GetUsername(owner) + + const char *SDP_GetUsername(SDP_Owner *owner); + +This function retrieves the username from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the username. + +=item Parameters + +=over 4 + +=item owner + +The C struct to retrieve the username from. + +=back + +=back + +=head2 SDP_GetSessionID(owner) + + const char *SDP_GetSessionID(SDP_Owner *owner); + +This function retrieves the session iD from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the session iD. + +=item Parameters + +=over 4 + +=item owner + +The C struct to retrieve the session iD from. + +=back + +=back + +=head2 SDP_GetSessionVersion(owner) + + const char *SDP_GetSessionVersion(SDP_Owner *owner); + +This function retrieves the session version from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the session version. + +=item Parameters + +=over 4 + +=item owner + +The C struct to retrieve the session version from. + +=back + +=back + +=head2 SDP_GetOwnerNetworkType(owner) + + const char *SDP_GetOwnerNetworkType(SDP_Owner *owner); + +This function retrieves the owner network type from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the owner network type. + +=item Parameters + +=over 4 + +=item owner + +The C struct to retrieve the owner network type from. + +=back + +=back + +=head2 SDP_GetOwnerAddressType(owner) + + const char *SDP_GetOwnerAddressType(SDP_Owner *owner); + +This function retrieves the owner address type from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the owner address type. + +=item Parameters + +=over 4 + +=item owner + +The C struct to retrieve the owner address type from. + +=back + +=back + +=head2 SDP_GetOwnerAddress(owner) + + const char *SDP_GetOwnerAddress(SDP_Owner *owner); + +This function retrieves the owner address from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the owner address. + +=item Parameters + +=over 4 + +=item owner + +The C struct to retrieve the owner address from. + +=back + +=back + +=head2 SDP_GetSessionName(description) + + const char *SDP_GetSessionName(SDP_Description *description); + +This function retrieves the session name from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the session name. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the session name from. + +=back + +=back + +=head2 SDP_GetSessionInformation(description) + + const char *SDP_GetSessionInformation(SDP_Description *description); + +This function retrieves the session information from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the session information. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the session information from. + +=back + +=back + +=head2 SDP_GetURI(description) + + const char *SDP_GetURI(SDP_Description *description); + +This function retrieves the URI from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the URI. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the URI from. + +=back + +=back + +=head2 SDP_GetEmailContacts(description) + + SDP_EmailContact *SDP_GetEmailContacts(SDP_Description *description); + +This function retrieves the email contacts from an C struct. + +=over 4 + +=item Return Value + +A pointer to the email contacts. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the email contacts from. + +=back + +=back + +=head2 SDP_GetNextEmailContact(email_contact) + + #define SDP_GetNextEmailContact SDP_GetNext + +Gets the next C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the next C struct in the linked list or NULL if there is none. + +=item Parameters + +=over 4 + +=item email_contact + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetPreviousEmailContact(email_contact) + + #define SDP_GetPreviousEmailContact SDP_GetPrevious + +Gets the previous C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the previous C struct in the linked list, or NULL if there is none. + +=item Parameters + +=over 4 + +=item email_contact + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetEmailAddress(email_contact) + + const char *SDP_GetEmailAddress(SDP_EmailContact *email_contact); + +This function retrieves the email address from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the email address. + +=item Parameters + +=over 4 + +=item email_contact + +The C struct to retrieve the email address from. + +=back + +=back + +=head2 SDP_GetEmailName(email_contact) + + const char *SDP_GetEmailName(SDP_EmailContact *email_contact); + +This function retrieves the email name from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the email name. + +=item Parameters + +=over 4 + +=item email_contact + +The C struct to retrieve the email name from. + +=back + +=back + +=head2 SDP_RemoveEmailContact(description, email_contact) + + void SDP_RemoveEmailContact( + SDP_Description * description, + SDP_EmailContact * email_contact + ); + +This removes (but does not destroy) the specified C +struct from the email contact list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the list. + +=item email_contact + +A pointer to the C you want removed from the list. + +=back + +=back + +=head2 SDP_GetPhoneContacts(description) + + SDP_PhoneContact *SDP_GetPhoneContacts(SDP_Description *description); + +This function retrieves the phone contacts from an C struct. + +=over 4 + +=item Return Value + +A pointer to the phone contacts. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the phone contacts from. + +=back + +=back + +=head2 SDP_GetNextPhoneContact(phone_contact) + + #define SDP_GetNextPhoneContact SDP_GetNext + +Gets the next C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the next C struct in the linked list or NULL if there is none. + +=item Parameters + +=over 4 + +=item phone_contact + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetPreviousPhoneContact(phone_contact) + + #define SDP_GetPreviousPhoneContact SDP_GetPrevious + +Gets the previous C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the previous C struct in the linked list, or NULL if there is none. + +=item Parameters + +=over 4 + +=item phone_contact + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetPhoneNumber(phone_contact) + + const char *SDP_GetPhoneNumber(SDP_PhoneContact *phone_contact); + +This function retrieves the phone number from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the phone number. + +=item Parameters + +=over 4 + +=item phone_contact + +The C struct to retrieve the phone number from. + +=back + +=back + +=head2 SDP_GetPhoneName(phone_contact) + + const char *SDP_GetPhoneName(SDP_PhoneContact *phone_contact); + +This function retrieves the phone name from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the phone name. + +=item Parameters + +=over 4 + +=item phone_contact + +The C struct to retrieve the phone name from. + +=back + +=back + +=head2 SDP_RemovePhoneContact(description, phone_contact) + + void SDP_RemovePhoneContact( + SDP_Description * description, + SDP_PhoneContact * phone_contact + ); + +This removes (but does not destroy) the specified C +struct from the phone contact list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the list. + +=item phone_contact + +A pointer to the C you want removed from the list. + +=back + +=back + +=head2 SDP_GetConnection(description) + + SDP_Connection *SDP_GetConnection(SDP_Description *description); + +This function retrieves the connection from an C struct. + +=over 4 + +=item Return Value + +A pointer to the connection. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the connection from. + +=back + +=back + +=head2 SDP_GetConnectionNetworkType(connection) + + const char *SDP_GetConnectionNetworkType(SDP_Connection *connection); + +This function retrieves the connection network type from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the connection network type. + +=item Parameters + +=over 4 + +=item connection + +The C struct to retrieve the connection network type from. + +=back + +=back + +=head2 SDP_GetConnectionAddressType(connection) + + const char *SDP_GetConnectionAddressType(SDP_Connection *connection); + +This function retrieves the connection address type from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the connection address type. + +=item Parameters + +=over 4 + +=item connection + +The C struct to retrieve the connection address type from. + +=back + +=back + +=head2 SDP_GetConnectionAddress(connection) + + const char *SDP_GetConnectionAddress(SDP_Connection *connection); + +This function retrieves the connection address from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the connection address. + +=item Parameters + +=over 4 + +=item connection + +The C struct to retrieve the connection address from. + +=back + +=back + +=head2 SDP_GetConnectionTTL(connection) + + int SDP_GetConnectionTTL(SDP_Connection *connection); + +This function retrieves the connection tTL from an C struct. + +=over 4 + +=item Return Value + +The connection tTL. + +=item Parameters + +=over 4 + +=item connection + +The C struct to retrieve the connection tTL from. + +=back + +=back + +=head2 SDP_GetTotalConnectionAddresses(connection) + + int SDP_GetTotalConnectionAddresses(SDP_Connection *connection); + +This function retrieves the total connection addresses from an C struct. + +=over 4 + +=item Return Value + +The total connection addresses. + +=item Parameters + +=over 4 + +=item connection + +The C struct to retrieve the total connection addresses from. + +=back + +=back + +=head2 SDP_GetBandwidth(description) + + SDP_Bandwidth *SDP_GetBandwidth(SDP_Description *description); + +This function retrieves the bandwidth from an C struct. + +=over 4 + +=item Return Value + +A pointer to the bandwidth. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the bandwidth from. + +=back + +=back + +=head2 SDP_GetBandwidthModifier(bandwidth) + + const char *SDP_GetBandwidthModifier(SDP_Bandwidth *bandwidth); + +This function retrieves the bandwidth modifier from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the bandwidth modifier. + +=item Parameters + +=over 4 + +=item bandwidth + +The C struct to retrieve the bandwidth modifier from. + +=back + +=back + +=head2 SDP_GetBandwidthValue(bandwidth) + + long SDP_GetBandwidthValue(SDP_Bandwidth *bandwidth); + +This function retrieves the bandwidth value from an C struct. + +=over 4 + +=item Return Value + +The bandwidth value. + +=item Parameters + +=over 4 + +=item bandwidth + +The C struct to retrieve the bandwidth value from. + +=back + +=back + +=head2 SDP_GetSessionPlayTimes(description) + + SDP_SessionPlayTime *SDP_GetSessionPlayTimes( + SDP_Description *description + ); + +This function retrieves the session play times from an C struct. + +=over 4 + +=item Return Value + +A pointer to the session play times. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the session play times from. + +=back + +=back + +=head2 SDP_GetNextSessionPlayTime(session_play_time) + + #define SDP_GetNextSessionPlayTime SDP_GetNext + +Gets the next C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the next C struct in the linked list or NULL if there is none. + +=item Parameters + +=over 4 + +=item session_play_time + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetPreviousSessionPlayTime(session_play_time) + + #define SDP_GetPreviousSessionPlayTime SDP_GetPrevious + +Gets the previous C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the previous C struct in the linked list, or NULL if there is none. + +=item Parameters + +=over 4 + +=item session_play_time + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetStartTime(session_play_time) + + time_t SDP_GetStartTime(SDP_SessionPlayTime *session_play_time); + +This function retrieves the start time from an C struct. + +=over 4 + +=item Return Value + +The start time. + +=item Parameters + +=over 4 + +=item session_play_time + +The C struct to retrieve the start time from. + +=back + +=back + +=head2 SDP_GetEndTime(session_play_time) + + time_t SDP_GetEndTime(SDP_SessionPlayTime *session_play_time); + +This function retrieves the end time from an C struct. + +=over 4 + +=item Return Value + +The end time. + +=item Parameters + +=over 4 + +=item session_play_time + +The C struct to retrieve the end time from. + +=back + +=back + +=head2 SDP_GetRepeatTimes(session_play_time) + + SDP_RepeatTime *SDP_GetRepeatTimes( + SDP_SessionPlayTime *session_play_time + ); + +This function retrieves the repeat times from an C struct. + +=over 4 + +=item Return Value + +A pointer to the repeat times. + +=item Parameters + +=over 4 + +=item session_play_time + +The C struct to retrieve the repeat times from. + +=back + +=back + +=head2 SDP_GetNextRepeatTime(repeat_time) + + #define SDP_GetNextRepeatTime SDP_GetNext + +Gets the next C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the next C struct in the linked list or NULL if there is none. + +=item Parameters + +=over 4 + +=item repeat_time + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetPreviousRepeatTime(repeat_time) + + #define SDP_GetPreviousRepeatTime SDP_GetPrevious + +Gets the previous C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the previous C struct in the linked list, or NULL if there is none. + +=item Parameters + +=over 4 + +=item repeat_time + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetRepeatInterval(repeat_time) + + unsigned long SDP_GetRepeatInterval(SDP_RepeatTime *repeat_time); + +This function retrieves the repeat interval from an C struct. + +=over 4 + +=item Return Value + +The repeat interval. + +=item Parameters + +=over 4 + +=item repeat_time + +The C struct to retrieve the repeat interval from. + +=back + +=back + +=head2 SDP_GetActiveDuration(repeat_time) + + unsigned long SDP_GetActiveDuration(SDP_RepeatTime *repeat_time); + +This function retrieves the active duration from an C struct. + +=over 4 + +=item Return Value + +The active duration. + +=item Parameters + +=over 4 + +=item repeat_time + +The C struct to retrieve the active duration from. + +=back + +=back + +=head2 SDP_GetRepeatOffsets(repeat_time) + + unsigned long *SDP_GetRepeatOffsets(SDP_RepeatTime *repeat_time); + +This function retrieves the repeat offsets from an C struct. + +=over 4 + +=item Return Value + +A pointer to the repeat offsets. + +=item Parameters + +=over 4 + +=item repeat_time + +The C struct to retrieve the repeat offsets from. + +=back + +=back + +=head2 SDP_GetTotalRepeatOffsets(repeat_time) + + int SDP_GetTotalRepeatOffsets(SDP_RepeatTime *repeat_time); + +This function retrieves the total repeat offsets from an C struct. + +=over 4 + +=item Return Value + +The total repeat offsets. + +=item Parameters + +=over 4 + +=item repeat_time + +The C struct to retrieve the total repeat offsets from. + +=back + +=back + +=head2 SDP_RemoveRepeatTime(session_play_times, repeat_time) + + void SDP_RemoveRepeatTime( + SDP_SessionPlayTime * session_play_times, + SDP_RepeatTime * repeat_time + ); + +This removes (but does not destroy) the specified C +struct from the repeat time list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item session_play_times + +A pointer to the C struct containing the list. + +=item repeat_time + +A pointer to the C you want removed from the list. + +=back + +=back + +=head2 SDP_RemoveSessionPlayTime(description, session_play_time) + + void SDP_RemoveSessionPlayTime( + SDP_Description * description, + SDP_SessionPlayTime * session_play_time + ); + +This removes (but does not destroy) the specified C +struct from the session play time list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the list. + +=item session_play_time + +A pointer to the C you want removed from the list. + +=back + +=back + +=head2 SDP_GetZoneAdjustments(description) + + SDP_ZoneAdjustment *SDP_GetZoneAdjustments(SDP_Description *description); + +This function retrieves the zone adjustments from an C struct. + +=over 4 + +=item Return Value + +A pointer to the zone adjustments. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the zone adjustments from. + +=back + +=back + +=head2 SDP_GetNextZoneAdjustment(zone_adjustment) + + #define SDP_GetNextZoneAdjustment SDP_GetNext + +Gets the next C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the next C struct in the linked list or NULL if there is none. + +=item Parameters + +=over 4 + +=item zone_adjustment + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetPreviousZoneAdjustment(zone_adjustment) + + #define SDP_GetPreviousZoneAdjustment SDP_GetPrevious + +Gets the previous C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the previous C struct in the linked list, or NULL if there is none. + +=item Parameters + +=over 4 + +=item zone_adjustment + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetZoneAdjustmentTime(zone_adjustment) + + time_t SDP_GetZoneAdjustmentTime(SDP_ZoneAdjustment *zone_adjustment); + +This function retrieves the zone adjustment time from an C struct. + +=over 4 + +=item Return Value + +The zone adjustment time. + +=item Parameters + +=over 4 + +=item zone_adjustment + +The C struct to retrieve the zone adjustment time from. + +=back + +=back + +=head2 SDP_GetZoneAdjustmentOffset(zone_adjustment) + + long SDP_GetZoneAdjustmentOffset(SDP_ZoneAdjustment *zone_adjustment); + +This function retrieves the zone adjustment offset from an C struct. + +=over 4 + +=item Return Value + +The zone adjustment offset. + +=item Parameters + +=over 4 + +=item zone_adjustment + +The C struct to retrieve the zone adjustment offset from. + +=back + +=back + +=head2 SDP_RemoveZoneAdjustment(description, zone_adjustment) + + void SDP_RemoveZoneAdjustment( + SDP_Description * description, + SDP_ZoneAdjustment * zone_adjustment + ); + +This removes (but does not destroy) the specified C +struct from the zone adjustment list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the list. + +=item zone_adjustment + +A pointer to the C you want removed from the list. + +=back + +=back + +=head2 SDP_GetEncryption(description) + + SDP_Encryption *SDP_GetEncryption(SDP_Description *description); + +This function retrieves the encryption from an C struct. + +=over 4 + +=item Return Value + +A pointer to the encryption. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the encryption from. + +=back + +=back + +=head2 SDP_GetEncryptionMethod(encryption) + + const char *SDP_GetEncryptionMethod(SDP_Encryption *encryption); + +This function retrieves the encryption method from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the encryption method. + +=item Parameters + +=over 4 + +=item encryption + +The C struct to retrieve the encryption method from. + +=back + +=back + +=head2 SDP_GetEncryptionKey(encryption) + + const char *SDP_GetEncryptionKey(SDP_Encryption *encryption); + +This function retrieves the encryption key from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the encryption key. + +=item Parameters + +=over 4 + +=item encryption + +The C struct to retrieve the encryption key from. + +=back + +=back + +=head2 SDP_GetAttributes(description) + + SDP_Attribute *SDP_GetAttributes(SDP_Description *description); + +This function retrieves the attributes from an C struct. + +=over 4 + +=item Return Value + +A pointer to the attributes. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the attributes from. + +=back + +=back + +=head2 SDP_GetNextAttribute(attribute) + + #define SDP_GetNextAttribute SDP_GetNext + +Gets the next C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the next C struct in the linked list or NULL if there is none. + +=item Parameters + +=over 4 + +=item attribute + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetPreviousAttribute(attribute) + + #define SDP_GetPreviousAttribute SDP_GetPrevious + +Gets the previous C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the previous C struct in the linked list, or NULL if there is none. + +=item Parameters + +=over 4 + +=item attribute + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetAttributeName(attribute) + + const char *SDP_GetAttributeName(SDP_Attribute *attribute); + +This function retrieves the attribute name from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the attribute name. + +=item Parameters + +=over 4 + +=item attribute + +The C struct to retrieve the attribute name from. + +=back + +=back + +=head2 SDP_GetAttributeValue(attribute) + + const char *SDP_GetAttributeValue(SDP_Attribute *attribute); + +This function retrieves the attribute value from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the attribute value. + +=item Parameters + +=over 4 + +=item attribute + +The C struct to retrieve the attribute value from. + +=back + +=back + +=head2 SDP_RemoveAttribute(description, attribute) + + void SDP_RemoveAttribute( + SDP_Description * description, + SDP_Attribute * attribute + ); + +This removes (but does not destroy) the specified C +struct from the attribute list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the list. + +=item attribute + +A pointer to the C you want removed from the list. + +=back + +=back + +=head2 SDP_GetMediaDescriptions(description) + + SDP_MediaDescription *SDP_GetMediaDescriptions( + SDP_Description *description + ); + +This function retrieves the media descriptions from an C struct. + +=over 4 + +=item Return Value + +A pointer to the media descriptions. + +=item Parameters + +=over 4 + +=item description + +The C struct to retrieve the media descriptions from. + +=back + +=back + +=head2 SDP_GetNextMediaDescription(media_description) + + #define SDP_GetNextMediaDescription SDP_GetNext + +Gets the next C struct from the linked list. + +=over 4 + +=item Return Value + +A pointer to the next C struct in the linked list or NULL if there is none. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GetMediaType(media_description) + + const char *SDP_GetMediaType(SDP_MediaDescription *media_description); + +This function retrieves the media type from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the media type. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the media type from. + +=back + +=back + +=head2 SDP_GetMediaPort(media_description) + + unsigned short SDP_GetMediaPort(SDP_MediaDescription *media_description); + +This function retrieves the media port from an C struct. + +=over 4 + +=item Return Value + +The media port. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the media port from. + +=back + +=back + +=head2 SDP_GetTotalMediaPorts(media_description) + + unsigned short SDP_GetTotalMediaPorts( + SDP_MediaDescription *media_description + ); + +This function retrieves the total media ports from an C struct. + +=over 4 + +=item Return Value + +The total media ports. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the total media ports from. + +=back + +=back + +=head2 SDP_GetMediaTransportProtocol(media_description) + + const char *SDP_GetMediaTransportProtocol( + SDP_MediaDescription *media_description + ); + +This function retrieves the media transport protocol from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the media transport protocol. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the media transport protocol from. + +=back + +=back + +=head2 SDP_GetMediaFormats(media_description) + + const char *SDP_GetMediaFormats(SDP_MediaDescription *media_description); + +This function retrieves the media formats from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the media formats. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the media formats from. + +=back + +=back + +=head2 SDP_GetMediaInformation(media_description) + + const char *SDP_GetMediaInformation( + SDP_MediaDescription *media_description + ); + +This function retrieves the media information from an C struct. + +=over 4 + +=item Return Value + +A pointer to the string containing the media information. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the media information from. + +=back + +=back + +=head2 SDP_GetMediaConnection(media_description) + + SDP_Connection *SDP_GetMediaConnection( + SDP_MediaDescription *media_description + ); + +This function retrieves the media connection from an C struct. + +=over 4 + +=item Return Value + +A pointer to the media connection. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the media connection from. + +=back + +=back + +=head2 SDP_GetMediaBandwidth(media_description) + + SDP_Bandwidth *SDP_GetMediaBandwidth( + SDP_MediaDescription *media_description + ); + +This function retrieves the media bandwidth from an C struct. + +=over 4 + +=item Return Value + +A pointer to the media bandwidth. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the media bandwidth from. + +=back + +=back + +=head2 SDP_GetMediaEncryption(media_description) + + SDP_Encryption *SDP_GetMediaEncryption( + SDP_MediaDescription *media_description + ); + +This function retrieves the media encryption from an C struct. + +=over 4 + +=item Return Value + +A pointer to the media encryption. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the media encryption from. + +=back + +=back + +=head2 SDP_GetMediaAttributes(media_description) + + SDP_Attribute *SDP_GetMediaAttributes( + SDP_MediaDescription *media_description + ); + +This function retrieves the media attributes from an C struct. + +=over 4 + +=item Return Value + +A pointer to the media attributes. + +=item Parameters + +=over 4 + +=item media_description + +The C struct to retrieve the media attributes from. + +=back + +=back + +=head2 SDP_RemoveMediaDescription(description, media_description) + + void SDP_RemoveMediaDescription( + SDP_Description * description, + SDP_MediaDescription * media_description + ); + +This removes (but does not destroy) the specified C +struct from the media description list. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct containing the list. + +=item media_description + +A pointer to the C you want removed from the list. + +=back + +=back + +=head1 DESTRUCTOR FUNCTIONS + +These functions destroy dynamically allocated structures. + +=head2 SDP_DestroyDescriptions(descriptions) + + void SDP_DestroyDescriptions(SDP_Description *descriptions); + +This function destroys a descriptions linked list from an +C struct, releasing its memory back to the operating system. +Do not try to use any items from the descriptions linked list after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item descriptions + +A pointer to the C struct to destroy the descriptions from. + +=back + +=back + +=head2 SDP_DestroyDescription(description) + + void SDP_DestroyDescription(SDP_Description *description); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyOwner(owner) + + void SDP_DestroyOwner(SDP_Owner *owner); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item owner + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyEmailContacts(description) + + void SDP_DestroyEmailContacts(SDP_Description *description); + +This function destroys a email contacts linked list from an +C struct, releasing its memory back to the operating system. +Do not try to use any items from the email contacts linked list after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct to destroy the email contacts from. + +=back + +=back + +=head2 SDP_DestroyEmailContact(email_contact) + + void SDP_DestroyEmailContact(SDP_EmailContact *email_contact); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item email_contact + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyPhoneContacts(description) + + void SDP_DestroyPhoneContacts(SDP_Description *description); + +This function destroys a phone contacts linked list from an +C struct, releasing its memory back to the operating system. +Do not try to use any items from the phone contacts linked list after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct to destroy the phone contacts from. + +=back + +=back + +=head2 SDP_DestroyPhoneContact(phone_contact) + + void SDP_DestroyPhoneContact(SDP_PhoneContact *phone_contact); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item phone_contact + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyConnection(connection) + + void SDP_DestroyConnection(SDP_Connection *connection); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item connection + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyBandwidth(bandwidth) + + void SDP_DestroyBandwidth(SDP_Bandwidth *bandwidth); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item bandwidth + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroySessionPlayTimes(description) + + void SDP_DestroySessionPlayTimes(SDP_Description *description); + +This function destroys a session play times linked list from an +C struct, releasing its memory back to the operating system. +Do not try to use any items from the session play times linked list after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct to destroy the session play times from. + +=back + +=back + +=head2 SDP_DestroySessionPlayTime(session_play_time) + + void SDP_DestroySessionPlayTime(SDP_SessionPlayTime *session_play_time); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item session_play_time + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyRepeatTimes(session_play_time) + + void SDP_DestroyRepeatTimes(SDP_SessionPlayTime *session_play_time); + +This function destroys a repeat times linked list from an +C struct, releasing its memory back to the operating system. +Do not try to use any items from the repeat times linked list after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item session_play_time + +A pointer to the C struct to destroy the repeat times from. + +=back + +=back + +=head2 SDP_DestroyRepeatTime(repeat_time) + + void SDP_DestroyRepeatTime(SDP_RepeatTime *repeat_time); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item repeat_time + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyZoneAdjustments(description) + + void SDP_DestroyZoneAdjustments(SDP_Description *description); + +This function destroys a zone adjustments linked list from an +C struct, releasing its memory back to the operating system. +Do not try to use any items from the zone adjustments linked list after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct to destroy the zone adjustments from. + +=back + +=back + +=head2 SDP_DestroyZoneAdjustment(zone_adjustment) + + void SDP_DestroyZoneAdjustment(SDP_ZoneAdjustment *zone_adjustment); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item zone_adjustment + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyEncryption(encryption) + + void SDP_DestroyEncryption(SDP_Encryption *encryption); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item encryption + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyAttributes(description) + + void SDP_DestroyAttributes(SDP_Description *description); + +This function destroys an attributes linked list from an +C struct, releasing its memory back to the operating system. +Do not try to use any items from the attributes linked list after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct to destroy the attributes from. + +=back + +=back + +=head2 SDP_DestroyAttribute(attribute) + + void SDP_DestroyAttribute(SDP_Attribute *attribute); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item attribute + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyMediaDescriptions(description) + + void SDP_DestroyMediaDescriptions(SDP_Description *description); + +This function destroys a media descriptions linked list from an +C struct, releasing its memory back to the operating system. +Do not try to use any items from the media descriptions linked list after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item description + +A pointer to the C struct to destroy the media descriptions from. + +=back + +=back + +=head2 SDP_DestroyMediaDescription(media_description) + + void SDP_DestroyMediaDescription(SDP_MediaDescription *media_description); + +This function destroys a C struct, releasing +its memory back to the operating system. Do not try to use the struct or any part of +it again after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct to destroy. + +=back + +=back + +=head2 SDP_DestroyMediaAttributes(media_description) + + void SDP_DestroyMediaAttributes(SDP_MediaDescription *media_description); + +This function destroys a media attributes linked list from an +C struct, releasing its memory back to the operating system. +Do not try to use any items from the media attributes linked list after destroying it. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item media_description + +A pointer to the C struct to destroy the media attributes from. + +=back + +=back + +=head1 BUGS + +Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse + +You can also email me directly: +. + +=head1 COPYRIGHT + +Copyright 2004 by William G. Davis. + +This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. + +=cut diff --git a/src/sdp_lib/SinisterSdpError.html b/src/sdp_lib/SinisterSdpError.html new file mode 100644 index 0000000..a730d58 --- /dev/null +++ b/src/sdp_lib/SinisterSdpError.html @@ -0,0 +1,365 @@ + + + + +SinisterSdpError.pod + + + + + + +
+

NAME

+ +

SinisterSdpError - SinisterSdp error handling.

+

SYNOPSIS

+ +
 #include <stdarg.h>
+ #include <stdio.h>
+ #include <SDP/SDP_Parser.h>
+ 
+ /* Function to quit: */
+ int quit(const char *format, ...)
+ {
+ 	va_list arg;
+ 
+ 	va_start(format, arg);
+ 	vfprintf(stderr, format, arg);
+ 	va_end(arg);
+ 
+ 	exit(0);
+ }
+ 
+ /* Error handlers that can be registered: */
+ void fatal_error_handler(SDP_Error error_code, const char *error_string)
+ {
+ 	quit("An error has occurred: %s", error_string);
+ }
+ int non_fatal_error_handler(SDP_Error error_code, const char *error_string)
+ {
+ 	fprintf(stderr, "WARNING: %s", error_string);
+	return 1; /* Keep going... */
+ }
+ 
+ int main(void)
+ {
+ 	SDP_Parser *parser;
+ 	SDP_Description *description;
+ 
+ 	parser = SDP_NewParser();
+ 	if (parser == NULL)
+		quit("Error: %s\n", SDP_GetLastErrorString());
+ 
+ 	description = SDP_ParseFile(parser, './sessions/description.sdp');
+ 	if (description == NULL)
+ 		quit("Couldn't parse: %s\n", SDP_GetLastErrorString());
+ 
+ 	...
+ 
+ 	/* Or, instead, register the error handlers: */
+ 	SDP_SetFatalErrorHandler(fatal_error_handler);
+ 	SDP_SetNonFatalErrorHandler(fatal_error_handler);
+ 
+ 	/* Now you can just ignore all return codes: */
+ 	parser = SDP_NewParser();
+ 	description = SDP_ParseFile(parser, './sessions/description.sdp');
+
+	...
+ }
+
+
+

DESCRIPTION

+ +

SinisterSdp employs a standard error code system for handling errors. Functions +return either false values or NULL pointers to indicate failure, and error +codes and strings can be retrieved using SDP_GetLastError() and +SDP_GetLastErrorString().

+

In addition, you can register error handlers to catch and process errors as +they occur.

+

The error code variable, error string variable, and the variables that hold the +function pointers to the error handlers are the only real global variables +in SinisterSdp, and they are not reentrant and they are not thread-safe. +This was done to keep portability at a maximum and refrain from having to +introduce any platform-specific code into what is otherwise a relatively +straightforward text manipulating library.

+

If you need thread safety, go edit SDP_Error.c and put the variables in thread +local storage.

+

FUNCTIONS

+ +

The following functions are available:

+

SDP_GetLastError()

+ +
 SDP_Error SDP_GetLastError(void);
+
+
+

This function retrieves the error code of the last error that occurred. If some +function call fails, call this to find out why.

+
    +
  • Return Value
  • +

    This function returns the error code of the last error to occur from the global +error code variable.

    +

    The following error codes may be returned by SDP_GetLastError():

    +
      +
    • Fatal errors:
    • +
       SDP_ERR_OUT_OF_MEMORY
      + SDP_ERR_FILE_OPEN_FAILED
      +
      +
      +
    • Non-fatal errors:
    • +
       SDP_ERR_MALFORMED_LINE
      + SDP_ERR_MALFORMED_V_FIELD
      + SDP_ERR_MALFORMED_O_FIELD
      + SDP_ERR_MALFORMED_E_FIELD
      + SDP_ERR_MALFORMED_P_FIELD
      + SDP_ERR_MALFORMED_C_FIELD
      + SDP_ERR_MALFORMED_B_FIELD
      + SDP_ERR_MALFORMED_T_FIELD
      + SDP_ERR_MALFORMED_R_FIELD
      + SDP_ERR_MALFORMED_Z_FIELD
      + SDP_ERR_MALFORMED_K_FIELD
      + SDP_ERR_MALFORMED_A_FIELD
      + SDP_ERR_MALFORMED_M_FIELD
      + SDP_ERR_INVALID_TYPE_CHARACTER
      + SDP_ERR_MULTIPLE_UNIQUE_FIELDS
      + SDP_ERR_FIELDS_OUT_OF_SEQUENCE
      +
      +
      +
    +
  • Parameters
  • +

    None.

    +
+

SDP_GetLastErrorString()

+ +
 const char *SDP_GetLastErrorString(void);
+
+
+

In addition to error codes, SinisterSdp functions produce printable error +messages when they fail. these messages are generated on the fly and stored in +the global error string variable.

+
    +
  • Return Value
  • +

    A pointer to the global error string variable.

    +
  • Parameters
  • +

    None.

    +
+

SDP_ErrorRaised()

+ +
 int SDP_ErrorRaised(void);
+
+
+

Can be used to tell whether or not any error has occurred yet.

+
    +
  • Return Value
  • +

    Returns true if some error has been raised, false otherwise.

    +
  • Parameters
  • +

    None.

    +
+

SDP_SetFatalErrorHandler(handler)

+ +
 void SDP_SetFatalErrorHandler(SDP_FatalErrorHandler handler);
+
+
+

This function allows you to register a handler to be invoked when any "fatal" +error occurs. A fatal error being one that the routine you called cannot +continue after and must return prematurely.

+

Afterwards, any time a fatal error occurs, your handler will be invoked with +the error code as the first argument and the error string as the second.

+

Here's the prototype of a sample handler:

+
 void sample_fatal_error_handler(
+ 	SDP_Error      error_code,
+ 	const char *   error_string
+ );
+
+
+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • handler
    • +

      A pointer to the handler function to register. If NULL, nothing will be invoked +for fatal errors.

      +
    +
+

SDP_SetNonFatalErrorHandler(handler)

+ +
 void SDP_SetNonFatalErrorHandler(SDP_NonFatalErrorHandler handler);
+
+
+

This function allows you to register a non-fatal error handler to be invoked +for all non-fatal errors. Non-fatal errors being errors that the function you +called *can* continue safely after, but probably shouldn't. The return value +of your handler is used by the function you called to tell whether or not it +should keep going anyway. A true return value means it should, a false value +means it shouldn't.

+

Here's the prototype of a sample handler:

+
 int sample_non_fatal_error_handler(
+ 	SDP_Error      error_code,
+ 	const char *   error_string
+ );
+
+
+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • handler
    • +

      A pointer to the handler function to register. If NULL, nothing will be invoked +for non-fatal errors.

      +
    +
+

SDP_UseHandlersForErrors(use_handlers)

+ +
 void SDP_UseHandlersForErrors(int use_handlers);
+
+
+

This function allows you to turn on or turn off the error handlers by +specifying a true or false value respectively. When off, neither of the two +handlers will be invoked when errors occur.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • use_handlers
    • +

      Boolean true or false; invoke the error handlers when errors occur?

      +
    +
+

BUGS

+ +

Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse

+

You can also email me directly: +<william_g_davis at users dot sourceforge dot net>.

+

COPYRIGHT

+ +

Copyright 2004 by William G. Davis.

+

This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution.

+

This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE.

+ + +
diff --git a/src/sdp_lib/SinisterSdpError.pod b/src/sdp_lib/SinisterSdpError.pod new file mode 100644 index 0000000..fdc4522 --- /dev/null +++ b/src/sdp_lib/SinisterSdpError.pod @@ -0,0 +1,294 @@ +=head1 NAME + +SinisterSdpError - SinisterSdp error handling. + +=head1 SYNOPSIS + + #include + #include + #include + + /* Function to quit: */ + int quit(const char *format, ...) + { + va_list arg; + + va_start(format, arg); + vfprintf(stderr, format, arg); + va_end(arg); + + exit(0); + } + + /* Error handlers that can be registered: */ + void fatal_error_handler(SDP_Error error_code, const char *error_string) + { + quit("An error has occurred: %s", error_string); + } + int non_fatal_error_handler(SDP_Error error_code, const char *error_string) + { + fprintf(stderr, "WARNING: %s", error_string); + return 1; /* Keep going... */ + } + + int main(void) + { + SDP_Parser *parser; + SDP_Description *description; + + parser = SDP_NewParser(); + if (parser == NULL) + quit("Error: %s\n", SDP_GetLastErrorString()); + + description = SDP_ParseFile(parser, './sessions/description.sdp'); + if (description == NULL) + quit("Couldn't parse: %s\n", SDP_GetLastErrorString()); + + ... + + /* Or, instead, register the error handlers: */ + SDP_SetFatalErrorHandler(fatal_error_handler); + SDP_SetNonFatalErrorHandler(fatal_error_handler); + + /* Now you can just ignore all return codes: */ + parser = SDP_NewParser(); + description = SDP_ParseFile(parser, './sessions/description.sdp'); + + ... + } + +=head1 DESCRIPTION + +SinisterSdp employs a standard error code system for handling errors. Functions +return either false values or NULL pointers to indicate failure, and error +codes and strings can be retrieved using C and +C. + +In addition, you can register error handlers to catch and process errors as +they occur. + +The error code variable, error string variable, and the variables that hold the +function pointers to the error handlers are the only I global variables +in SinisterSdp, and they are B reentrant and they are B thread-safe. +This was done to keep portability at a maximum and refrain from having to +introduce any platform-specific code into what is otherwise a relatively +straightforward text manipulating library. + +If you need thread safety, go edit SDP_Error.c and put the variables in thread +local storage. + +=head1 FUNCTIONS + +The following functions are available: + +=head2 SDP_GetLastError() + + SDP_Error SDP_GetLastError(void); + +This function retrieves the error code of the last error that occurred. If some +function call fails, call this to find out why. + +=over 4 + +=item Return Value + +This function returns the error code of the last error to occur from the global +error code variable. + +The following error codes may be returned by C: + +=over 4 + +=item Fatal errors: + + SDP_ERR_OUT_OF_MEMORY + SDP_ERR_FILE_OPEN_FAILED + +=item Non-fatal errors: + + SDP_ERR_MALFORMED_LINE + SDP_ERR_MALFORMED_V_FIELD + SDP_ERR_MALFORMED_O_FIELD + SDP_ERR_MALFORMED_E_FIELD + SDP_ERR_MALFORMED_P_FIELD + SDP_ERR_MALFORMED_C_FIELD + SDP_ERR_MALFORMED_B_FIELD + SDP_ERR_MALFORMED_T_FIELD + SDP_ERR_MALFORMED_R_FIELD + SDP_ERR_MALFORMED_Z_FIELD + SDP_ERR_MALFORMED_K_FIELD + SDP_ERR_MALFORMED_A_FIELD + SDP_ERR_MALFORMED_M_FIELD + SDP_ERR_INVALID_TYPE_CHARACTER + SDP_ERR_MULTIPLE_UNIQUE_FIELDS + SDP_ERR_FIELDS_OUT_OF_SEQUENCE + +=back + +=item Parameters + +None. + +=back + +=head2 SDP_GetLastErrorString() + + const char *SDP_GetLastErrorString(void); + +In addition to error codes, SinisterSdp functions produce printable error +messages when they fail. these messages are generated on the fly and stored in +the global error string variable. + +=over 4 + +=item Return Value + +A pointer to the global error string variable. + +=item Parameters + +None. + +=back + +=head2 SDP_ErrorRaised() + + int SDP_ErrorRaised(void); + +Can be used to tell whether or not any error has occurred yet. + +=over 4 + +=item Return Value + +Returns true if some error has been raised, false otherwise. + +=item Parameters + +None. + +=back + +=head2 SDP_SetFatalErrorHandler(handler) + + void SDP_SetFatalErrorHandler(SDP_FatalErrorHandler handler); + +This function allows you to register a handler to be invoked when any "fatal" +error occurs. A fatal error being one that the routine you called cannot +continue after and must return prematurely. + +Afterwards, any time a fatal error occurs, your handler will be invoked with +the error code as the first argument and the error string as the second. + +Here's the prototype of a sample handler: + + void sample_fatal_error_handler( + SDP_Error error_code, + const char * error_string + ); + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item handler + +A pointer to the handler function to register. If NULL, nothing will be invoked +for fatal errors. + +=back + +=back + +=head2 SDP_SetNonFatalErrorHandler(handler) + + void SDP_SetNonFatalErrorHandler(SDP_NonFatalErrorHandler handler); + +This function allows you to register a non-fatal error handler to be invoked +for all non-fatal errors. Non-fatal errors being errors that the function you +called *can* continue safely after, but probably shouldn't. The return value +of your handler is used by the function you called to tell whether or not it +should keep going anyway. A true return value means it should, a false value +means it shouldn't. + +Here's the prototype of a sample handler: + + int sample_non_fatal_error_handler( + SDP_Error error_code, + const char * error_string + ); + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item handler + +A pointer to the handler function to register. If NULL, nothing will be invoked +for non-fatal errors. + +=back + +=back + +=head2 SDP_UseHandlersForErrors(use_handlers) + + void SDP_UseHandlersForErrors(int use_handlers); + +This function allows you to turn on or turn off the error handlers by +specifying a true or false value respectively. When off, neither of the two +handlers will be invoked when errors occur. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item use_handlers + +Boolean true or false; invoke the error handlers when errors occur? + +=back + +=back + +=head1 BUGS + +Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse + +You can also email me directly: +. + +=head1 COPYRIGHT + +Copyright 2004 by William G. Davis. + +This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. + +=cut + + diff --git a/src/sdp_lib/SinisterSdpGenerator.html b/src/sdp_lib/SinisterSdpGenerator.html new file mode 100644 index 0000000..35f2e83 --- /dev/null +++ b/src/sdp_lib/SinisterSdpGenerator.html @@ -0,0 +1,1282 @@ + + + + +SinisterSdpGenerator.pod + + + + +
+ +
+ +
+

NAME

+ +

SinisterSdpGenerator - The SDP generator routines

+

SYNOPSIS

+ +
 #include <SDP/SDP_Generator.h>
+ 
+ int main(void)
+ {
+ 	SDP_Generator *generator = SDP_NewGenerator();
+ 
+ 	SDP_GenProtocolVersionField(generator, 1);
+ 	SDP_GenOwnerField(
+ 		generator, "username", "session_id", "IN", "IP4", "127.0.0.1"
+ 	);
+ 	SDP_GenSessionNameField(generator, "Some session");
+ 	SDP_GenInformationField(generator, "This is short description");
+ 
+ 	...
+ 
+ 	SDP_SaveGeneratedOutput(generator, "description.sdp");
+ }
+
+
+

DESCRIPTION

+ +

This document describes the SinisterSdp generator routines. These routines +enable you programmatically generate SDP session descriptions, as well as +spit out descriptions encapsulated by an SDP_Description struct into a +string or file.

+

SDP_OutputDescriptionsToString(descriptions)

+ +
 char *SDP_OutputDescriptionsToString(SDP_Description *descriptions);
+
+
+

This function outputs every single SDP_Description struct in the linked list +to a dynamically allocated string.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the dynamically allocated string. +Otherwise, it returns a NULL pointer. Call SDP_GetLastError() for extended +error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         output the descriptions to the string.
    +
    +
    +
  • Parameters
  • +
      +
    • descriptions
    • +

      A pointer to an SDP_Description struct.

      +
    +
+

SDP_OutputDescriptionToString(description)

+ +
 char *SDP_OutputDescriptionToString(SDP_Description *description);
+
+
+

This function outputs a single SDP_Description struct to a dynamically +allocated string and returns a pointer to it.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the dynamically allocated string. +Otherwise, it returns a NULL pointer. Call SDP_GetLastError() for extended +error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         output the description to the string.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to an SDP_Description struct.

      +
    +
+

SDP_OutputDescriptionsToFile(descriptions, filename)

+ +
 int SDP_OutputDescriptionsToFile(
+ 	SDP_Description *   descriptions,
+ 	const char *        filename
+ );
+
+
+

This function outputs every SDP_Description struct in the link list to a +file. If the file specified does not exist, it will be created. If it does +exist, then anything in it will be overwritten.

+
    +
  • Return Value
  • +

    This function returns true if no error occurs, false otherwise. Call +SDP_GetLastError() for extended error information. The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY    - There isn't enough memory available to
    +                            output the descriptions to the
    +                            specified file.
    + SDP_ERR_FILE_OPEN_FAILED - The file you specified could not be
    +                            opened.
    +
    +
    +
  • Parameters
  • +
      +
    • descriptions
    • +

      A pointer to an SDP_Description struct.

      +
    • filename
    • +

      A pointer to a string containing the name of the file to write to.

      +
    +
+

SDP_OutputDescriptionToFile(description, filename)

+ +
 int SDP_OutputDescriptionToFile(
+ 	SDP_Description *   description,
+ 	const char *        filename
+ );
+
+
+

This function outputs a single SDP_Description struct to a file. If the file +specified does not exist, it will be created. If it does exist, then anything +in it will be overwritten.

+
    +
  • Return Value
  • +

    This function returns true if no error occurs, false otherwise. Call +SDP_GetLastError() for extended error information. The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY    - There isn't enough memory available to
    +                            output the description to the specified
    +                            file.
    + SDP_ERR_FILE_OPEN_FAILED - The file you specified could not be
    +                            opened.
    +
    +
    +
  • Parameters
  • +
      +
    • description
    • +

      A pointer to an SDP_Description struct.

      +
    • filename
    • +

      A pointer to a string containing the name of the file to write to.

      +
    +
+

SDP_NewGenerator()

+ +
 SDP_Generator *SDP_NewGenerator(void);
+
+
+

This function creates a new SDP generator.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly-created SDP_Generator +struct. Otherwise, it returns a NULL pointer instead. Call +SDP_GetLastError() for extended error information. The possible error codes +returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There wasn't enough memeory available to
    +                         create the generator.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_GenProtocolVersionField(generator, protocol_version)

+ +
 int SDP_GenProtocolVersionField(
+ 	SDP_Generator *   generator,
+ 	int               protocol_version
+ );
+
+
+

This function generates a "v" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "v" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • protocol_version
    • +

      The protocol version number.

      +
    +
+

SDP_GenOwnerField(generator, username, session_id, session_version, network_type, address_type, address)

+ +
 int SDP_GenOwnerField(
+ 	SDP_Generator *   generator,
+ 	const char *      username,
+ 	const char *      session_id,
+ 	const char *      session_version,
+ 	const char *      network_type,
+ 	const char *      address_type,
+ 	const char *      address
+ );
+
+
+

This function generates an "o" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "o" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • username
    • +

      A pointer to a string containing the username.

      +
    • session_id
    • +

      A pointer to a string containing the session ID.

      +
    • session_version
    • +

      A pointer to a string containing the session version number.

      +
    • network_type
    • +

      A pointer to a string containing the network type (e.g., "IN" for Internet).

      +
    • address_type
    • +

      A pointer to a string containing the address type (e.g., "IP4" for IPv4).

      +
    • address
    • +

      A pointer to a string containing the address.

      +
    +
+

SDP_GenFromOwner(generator, owner)

+ +
 int SDP_GenFromOwner(
+ 	SDP_Generator *   generator,
+ 	SDP_Owner *       owner
+ );
+
+
+

This function generates an "o" field from an SDP_Owner struct.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "o" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • owner
    • +

      A pointer to the SDP_Owner struct.

      +
    +
+

SDP_GenSessionNameField(generator, session_name)

+ +
 int SDP_GenSessionNameField(
+ 	SDP_Generator *   generator,
+ 	const char *      session_name
+ );
+
+
+

This function generates an "s" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "s" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • session_name
    • +

      A pointer to a string containing the name of the session.

      +
    +
+

SDP_GenInformationField(generator, information)

+ +
 int SDP_GenInformationField(
+ 	SDP_Generator *   generator,
+ 	const char *      information
+ );
+
+
+

This fucntion generates an "i" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "i" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • information
    • +

      A pointer to a string containing a short description of the session.

      +
    +
+

SDP_GenURIField(generator, uri)

+ +
 int SDP_GenURIField(
+ 	SDP_Generator *   generator,
+ 	const char *      uri
+ );
+
+
+

This function generates a "u" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "u" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • uri
    • +

      A pointer to a string containing the URI of the session.

      +
    +
+

SDP_GenEmailContactField(generator, address, name)

+ +
 int SDP_GenEmailContactField(
+ 	SDP_Generator *   generator,
+ 	const char *      address,
+ 	const char *      name
+ );
+
+
+

This function generates an "e" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "e" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • address
    • +

      A pointer to a string containing the email address.

      +
    • name
    • +

      A pointer to a string containing the name of the person who uses that email +address.

      +
    +
+

SDP_GenFromEmailContacts(generator, email_contacts)

+ +
 int SDP_GenFromEmailContacts(
+ 	SDP_Generator *      generator,
+ 	SDP_EmailContact *   email_contacts
+ );
+
+
+

This function generates "e" fields from each SDP_EmailContact struct in the +linked list.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "e" fields.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • email_contacts
    • +

      A pointer to an SDP_EmailContact struct.

      +
    +
+

SDP_GenFromEmailContact(generator, email_contact)

+ +
 int SDP_GenFromEmailContact(
+ 	SDP_Generator *      generator,
+ 	SDP_EmailContact *   email_contact
+ );
+
+
+

This function generates a single "e" field from a single SDP_EmailContact +struct.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "e" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • email_contact
    • +

      A pointer to the SDP_EmailContact struct.

      +
    +
+

SDP_GenPhoneContactField(generator, number, name)

+ +
 int SDP_GenPhoneContactField(
+ 	SDP_Generator *   generator,
+ 	const char *      number,
+ 	const char *      name
+ );
+
+
+

This function generates a "p" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "p" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • number
    • +

      A pointer to a string containing the phone number.

      +
    • name
    • +

      A pointer to a string containing the name of the person who can be reached at +that phone number.

      +
    +
+

SDP_GenFromPhoneContacts(generator, phone_contacts)

+ +
 int SDP_GenFromPhoneContacts(
+ 	SDP_Generator *      generator,
+ 	SDP_PhoneContact *   phone_contacts
+ );
+
+
+

This function generates "p" fields from every SDP_PhoneContact struct in the +linked list.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "p" fields.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • phone_contacts
    • +

      A pointer to an SDP_PhoneContact struct.

      +
    +
+

SDP_GenFromPhoneContact(generator, phone_contact)

+ +
 int SDP_GenFromPhoneContact(
+ 	SDP_Generator *      generator,
+ 	SDP_PhoneContact *   phone_contact
+ );
+
+
+

This function generates a "p" field from a single SDP_PhoneContact struct.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "p" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • phone_contact
    • +

      A pointer to an SDP_PhoneContact struct.

      +
    +
+

SDP_GenConnectionField(generator, network_type, address_type, address, ttl, total_addresses)

+ +
 int SDP_GenConnectionField(
+ 	SDP_Generator *   generator,
+ 	const char *      network_type,
+ 	const char *      address_type,
+ 	const char *      address,
+ 	int               ttl,
+ 	int               total_addresses
+ );
+
+
+

This function generates a "c" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "c" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • network_type
    • +

      A pointer to a string containing the network type (e.g., "IN" for Internet).

      +
    • address_type
    • +

      A pointer to a string containing the address type (e.g., "IP4" for Internet +Protocol version 4).

      +
    • address
    • +

      A pointer to a string containing the address.

      +
    • ttl
    • +

      Time To Live.

      +
    • total_addresses
    • +

      Counting up from "address", how many addresses are there available.

      +
    +
+

SDP_GenFromConnection(generator, connection)

+ +
 int SDP_GenFromConnection(
+ 	SDP_Generator *    generator,
+ 	SDP_Connection *   connection
+ );
+
+
+

This function generates a "c" field from an SDP_Connection struct.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "c" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • connection
    • +

      A pointer to an SDP_Connection struct.

      +
    +
+

SDP_GenBandwidthField(generator, modifier, value)

+ +
 int SDP_GenBandwidthField(
+ 	SDP_Generator *   generator,
+ 	const char *      modifier,
+ 	long              value
+ );
+
+
+

This function generates a "b" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "c" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • modifier
    • +

      A pointer to a string containing the bandwidth modifier (e.g., "CT" for +Conference Total).

      +
    • value
    • +

      A pointer to a string contianing the bandwidth value.

      +
    +
+

SDP_GenFromBandwidth(generator, bandwidth)

+ +
 int SDP_GenFromBandwidth(
+ 	SDP_Generator *   generator,
+ 	SDP_Bandwidth *   bandwidth
+ );
+
+
+

This function generates a "b" field from an SDP_Bandwidth struct.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "c" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • bandwidth
    • +

      A pointer to a SDP_Bandwidth struct.

      +
    +
+

SDP_GenSessionPlayTimeField(generator, start_time, end_time)

+ +
 int SDP_GenSessionPlayTimeField(
+ 	SDP_Generator *   generator,
+ 	time_t            start_time,
+ 	time_t            end_time
+ );
+
+
+

This function generates a "t" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "t" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • start_time
    • +

      A time_t value of when the session starts.

      +
    • end_time
    • +

      A time_t value of when the session ends.

      +
    +
+

SDP_GenFromSessionPlayTimes(generator, session_play_times)

+ +
 int SDP_GenFromSessionPlayTimes(
+ 	SDP_Generator *         generator,
+ 	SDP_SessionPlayTime *   session_play_times
+ );
+
+
+

This function generates a "t" field and any requisite "r" feilds for each +SDP_SessionPlayTime struct in the linked list.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "t" fields or "r" fields.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • session_play_times
    • +

      A pointer to SDP_SessionPlayTime struct.

      +
    +
+

SDP_GenFromSessionPlayTime(generator, session_play_time)

+ +
 int SDP_GenFromSessionPlayTime(
+ 	SDP_Generator *         generator,
+ 	SDP_SessionPlayTime *   session_play_time
+ );
+
+
+

This function generates a single "t" field and any requisite "r" fields from +a SDP_SessionPlayTime struct.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "t" field or "r" fields.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • session_play_time
    • +

      A pointer to a SDP_SessionPlayTime struct.

      +
    +
+

SDP_GenRepeatTimeField(generator, repeat_interval, active_duration, repeat_offsets)

+ +
 int SDP_GenRepeatTimeField(
+ 	SDP_Generator *   generator,
+ 	const char *      repeat_interval,
+ 	const char *      active_duration,
+ 	const char *      repeat_offsets
+ );
+
+
+

This function generates an "r" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "r" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • repeat_interval
    • +

      A pointer to a string containing the repeat interval as a number by itself +(meaning in seconds) or postfixed with the letter "m" (meaning in minutes), "h" +(meaning in hours), or "d" (meaning in days).

      +
    • active_duration
    • +

      A pointer to a string containing the active duration of the session as a number +by itself (meaning in seconds) or postfixed with the letter "m" (meaning in +minutes), "h" (meaning in hours), or "d" (meaning in days).

      +
    • repeat_offsets
    • +

      A string containing one or more repeat offsets seperated by spaces.

      +
    +
+

SDP_GenFromRepeatTimes(generator, repeat_times)

+ +
 int SDP_GenFromRepeatTimes(
+ 	SDP_Generator *    generator,
+ 	SDP_RepeatTime *   repeat_times
+ );
+
+
+

This function generates "r" fields from each SDP_RepeatTime struct in the +linked list.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "r" fields.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • repeat_times
    • +

      A pointer to a SDP_RepeatTime struct.

      +
    +
+

SDP_GenFromRepeatTime(generator, repeat_time)

+ +
 int SDP_GenFromRepeatTime(
+ 	SDP_Generator *    generator,
+ 	SDP_RepeatTime *   repeat_time
+ );
+
+
+

This function generates an "r" field from an SDP_RepeatTime struct.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "r" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • repeat_time
    • +

      A pointer to the SDP_RepeatTime strcut.

      +
    +
+

SDP_GenZoneAdjustmentsField(generator, total_adjustments, ...)

+ +
 int SDP_GenZoneAdjustmentsField(
+ 	SDP_Generator *   generator,
+ 	int               total_adjustments,
+ 	...
+ );
+
+
+

This function generates a "z" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "z" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • total_adjustments
    • +

      The number of time-zone adjustment pairs to expect.

      +
    • ...
    • +

      The remaining arguments come in pairs. The first is the time (as a time_t +value) of when some type of zone adjustment is to occur. The second is the +adjustment itself in the form of a string comprised of a positive or negative +number followed by a the letter "m" (meaning minutes), "h" (meaning hours), or +"d" (meaning days):

      +
       SDP_GenZoneAdjustmentsField(generator, 2,
      + 	some_time, "-1h",
      + 	some_other_time, "-2h"
      + );
      +
      +
      +

      Each time value will be converted from OS time to Network Protocol Time.

      +
    +
+

SDP_GenFromZoneAdjustments(generator, zone_adjustments)

+ +
 int SDP_GenFromZoneAdjustments(
+ 	SDP_Generator *        generator,
+ 	SDP_ZoneAdjustment *   zone_adjustments
+ );
+
+
+

Stub description documentation.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "z" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • zone_adjustments
    • +

      A pointer to an SDP_ZoneAdjustments struct.

      +
    +
+

SDP_GenEncryptionField(generator, method, key)

+ +
 int SDP_GenEncryptionField(
+ 	SDP_Generator *   generator,
+ 	const char *      method,
+ 	const char *      key
+ );
+
+
+

This function generates a "k" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "e" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • method
    • +

      A pointer to a string containing the encryption method.

      +
    • key
    • +

      A pointer to a string containing the encyption key.

      +
    +
+

SDP_GenFromEncryption(generator, encryption)

+ +
 int SDP_GenFromEncryption(
+ 	SDP_Generator *    generator,
+ 	SDP_Encryption *   encryption
+ );
+
+
+

This function generates a "k" field from an SDP_Encryption struct.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "k" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • encryption
    • +

      A pointer to an SDP_Encryption struct.

      +
    +
+

SDP_GenAttributeField(generator, name, value)

+ +
 int SDP_GenAttributeField(
+ 	SDP_Generator *   generator,
+ 	const char *      name,
+ 	const char *      value
+ );
+
+
+

This function generates an "a" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "a" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • name
    • +

      A pointer to a string containing the name of the attribute.

      +
    • value
    • +

      A pointer to a string containing the value of the attribute.

      +
    +
+

SDP_GenFromAttributes(generator, attributes)

+ +
 int SDP_GenFromAttributes(
+ 	SDP_Generator *   generator,
+ 	SDP_Attribute *   attributes
+ );
+
+
+

This function generates "a" fields from every SDP_Attribute struct in the +linked list.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "a" fields.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • attributes
    • +

      A pointer to an SDP_Attribute struct.

      +
    +
+

SDP_GenFromAttribute(generator, attribute)

+ +
 int SDP_GenFromAttribute(
+ 	SDP_Generator *   generator,
+ 	SDP_Attribute *   attribute
+ );
+
+
+

This function generates an "a" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "a" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • attribute
    • +

      A pointer to an SDP_Attribute struct.

      +
    +
+

SDP_GenMediaDescriptionField(generator, media_type, port, total_ports, transport_protocol, formats)

+ +
 int SDP_GenMediaDescriptionField(
+ 	SDP_Generator *   generator,
+ 	const char *      media_type,
+ 	const char *      port,
+ 	const char *      transport_protocol,
+ 	const char *      formats
+ );
+
+
+

This function generates an "m" field.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "m" field.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • media_type
    • +

      A pointer to a string containing the media type.

      +
    • port
    • +

      A pointer to a string containing the port number with an optional number of +other usable ports for UDP multicasts.

      +
    • transport_protocol
    • +

      A pointer to a string containing the transport protocol (e.g., "RTP/AVP").

      +
    • formats
    • +

      A pointer to a string containing media formats separated by spaces.

      +
    +
+

SDP_GenFromMediaDescriptions(generator, media_descriptions)

+ +
 int SDP_GenFromMediaDescriptions(
+ 	SDP_Generator *          generator,
+ 	SDP_MediaDescription *   media_descriptions
+ );
+
+
+

This function generates "m" fields and any other requisite fields from each +SDP_MediaDescription in the linked list.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to
    +                         generate the "m" fields.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • media_descriptions
    • +

      A pointer to an SDP_MediaDescription struct.

      +
    +
+

SDP_GenFromMediaDescription(generator, media_description)

+ +
 int SDP_GenFromMediaDescription(
+ 	SDP_Generator *          generator,
+ 	SDP_MediaDescription *   media_description
+ );
+
+
+

This function generates an "m" field and any related fields from an +SDP_MediaDescription struct.

+
    +
  • Return Value
  • +

    Stub return value documentation.

    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • media_description
    • +

      A pointer to an SDP_MediaDescription struct.

      +
    +
+

SDP_GetGeneratedOutput(generator)

+ +
 char *SDP_GetGeneratedOutput(SDP_Generator *generator);
+
+
+

This function returns a pointer to the generator's buffer. If you want to +modify the this or use it after calling SDP_DestroyGenerator(), use +strdup() or some comparable function to copy it.

+
    +
  • Return Value
  • +

    A pointer to the generator's output buffer.

    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    +
+

SDP_SaveGeneratedOutput(generator, filename)

+ +
 int SDP_SaveGeneratedOutput(
+ 	SDP_Generator *   generator,
+ 	const char *      filename
+ );
+
+
+

This function outputs the generator buffer to a file. If the file specified +doesn't already exist, then it will be created. If it does exist, then anything +in it will be overwritten.

+
    +
  • Return Value
  • +

    It returns ture if no error occurs, false otherwise. Call SDP_GetLastError() +for extended error information. The possible error codes returned are:

    +
     SDP_ERR_FILE_OPEN_FAILED - The file you specified could not
    +                            be opened.
    +
    +
    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct.

      +
    • filename
    • +

      A pointer to a string containing the name of the file to write to.

      +
    +
+

SDP_DestroyGenerator(generator)

+ +
 void SDP_DestroyGenerator(SDP_Generator *generator);
+
+
+

This function destroys an SDP generator, returning its memory to the system.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • generator
    • +

      A pointer to the SDP_Generator struct to destroy.

      +
    +
+

BUGS

+ +

Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse

+

You can also email me directly: +<william_g_davis at users dot sourceforge dot net>.

+

COPYRIGHT

+ +

Copyright 2004 by William G. Davis.

+

This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution.

+

This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE.

+ + +
diff --git a/src/sdp_lib/SinisterSdpGenerator.pod b/src/sdp_lib/SinisterSdpGenerator.pod new file mode 100644 index 0000000..bb2cb4e --- /dev/null +++ b/src/sdp_lib/SinisterSdpGenerator.pod @@ -0,0 +1,1556 @@ +=head1 NAME + +SinisterSdpGenerator - The SDP generator routines + +=head1 SYNOPSIS + + #include + + int main(void) + { + SDP_Generator *generator = SDP_NewGenerator(); + + SDP_GenProtocolVersionField(generator, 1); + SDP_GenOwnerField( + generator, "username", "session_id", "IN", "IP4", "127.0.0.1" + ); + SDP_GenSessionNameField(generator, "Some session"); + SDP_GenInformationField(generator, "This is short description"); + + ... + + SDP_SaveGeneratedOutput(generator, "description.sdp"); + } + +=head1 DESCRIPTION + +This document describes the SinisterSdp generator routines. These routines +enable you programmatically generate SDP session descriptions, as well as +spit out descriptions encapsulated by an C struct into a +string or file. + +=head2 SDP_OutputDescriptionsToString(descriptions) + + char *SDP_OutputDescriptionsToString(SDP_Description *descriptions); + +This function outputs every single C struct in the linked list +to a dynamically allocated string. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the dynamically allocated string. +Otherwise, it returns a NULL pointer. Call C for extended +error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + output the descriptions to the string. + +=item Parameters + +=over 4 + +=item descriptions + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_OutputDescriptionToString(description) + + char *SDP_OutputDescriptionToString(SDP_Description *description); + +This function outputs a single C struct to a dynamically +allocated string and returns a pointer to it. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the dynamically allocated string. +Otherwise, it returns a NULL pointer. Call C for extended +error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + output the description to the string. + +=item Parameters + +=over 4 + +=item description + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_OutputDescriptionsToFile(descriptions, filename) + + int SDP_OutputDescriptionsToFile( + SDP_Description * descriptions, + const char * filename + ); + +This function outputs every C struct in the link list to a +file. If the file specified does not exist, it will be created. If it does +exist, then anything in it will be overwritten. + +=over 4 + +=item Return Value + +This function returns true if no error occurs, false otherwise. Call +C for extended error information. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + output the descriptions to the + specified file. + SDP_ERR_FILE_OPEN_FAILED - The file you specified could not be + opened. + +=item Parameters + +=over 4 + +=item descriptions + +A pointer to an C struct. + +=item filename + +A pointer to a string containing the name of the file to write to. + +=back + +=back + +=head2 SDP_OutputDescriptionToFile(description, filename) + + int SDP_OutputDescriptionToFile( + SDP_Description * description, + const char * filename + ); + +This function outputs a single C struct to a file. If the file +specified does not exist, it will be created. If it does exist, then anything +in it will be overwritten. + +=over 4 + +=item Return Value + +This function returns true if no error occurs, false otherwise. Call +C for extended error information. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + output the description to the specified + file. + SDP_ERR_FILE_OPEN_FAILED - The file you specified could not be + opened. + +=item Parameters + +=over 4 + +=item description + +A pointer to an C struct. + +=item filename + +A pointer to a string containing the name of the file to write to. + +=back + +=back + +=head2 SDP_NewGenerator() + + SDP_Generator *SDP_NewGenerator(void); + +This function creates a new SDP generator. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly-created C +struct. Otherwise, it returns a NULL pointer instead. Call +C for extended error information. The possible error codes +returned are: + + SDP_ERR_OUT_OF_MEMORY - There wasn't enough memeory available to + create the generator. + +=item Parameters + +None. + +=back + +=head2 SDP_GenProtocolVersionField(generator, protocol_version) + + int SDP_GenProtocolVersionField( + SDP_Generator * generator, + int protocol_version + ); + +This function generates a "v" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "v" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item protocol_version + +The protocol version number. + +=back + +=back + +=head2 SDP_GenOwnerField(generator, username, session_id, session_version, network_type, address_type, address) + + int SDP_GenOwnerField( + SDP_Generator * generator, + const char * username, + const char * session_id, + const char * session_version, + const char * network_type, + const char * address_type, + const char * address + ); + +This function generates an "o" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "o" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item username + +A pointer to a string containing the username. + +=item session_id + +A pointer to a string containing the session ID. + +=item session_version + +A pointer to a string containing the session version number. + +=item network_type + +A pointer to a string containing the network type (e.g., "IN" for Internet). + +=item address_type + +A pointer to a string containing the address type (e.g., "IP4" for IPv4). + +=item address + +A pointer to a string containing the address. + +=back + +=back + +=head2 SDP_GenFromOwner(generator, owner) + + int SDP_GenFromOwner( + SDP_Generator * generator, + SDP_Owner * owner + ); + +This function generates an "o" field from an C struct. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "o" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item owner + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GenSessionNameField(generator, session_name) + + int SDP_GenSessionNameField( + SDP_Generator * generator, + const char * session_name + ); + +This function generates an "s" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "s" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item session_name + +A pointer to a string containing the name of the session. + +=back + +=back + +=head2 SDP_GenInformationField(generator, information) + + int SDP_GenInformationField( + SDP_Generator * generator, + const char * information + ); + +This fucntion generates an "i" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "i" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item information + +A pointer to a string containing a short description of the session. + +=back + +=back + +=head2 SDP_GenURIField(generator, uri) + + int SDP_GenURIField( + SDP_Generator * generator, + const char * uri + ); + +This function generates a "u" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "u" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item uri + +A pointer to a string containing the URI of the session. + +=back + +=back + +=head2 SDP_GenEmailContactField(generator, address, name) + + int SDP_GenEmailContactField( + SDP_Generator * generator, + const char * address, + const char * name + ); + +This function generates an "e" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "e" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item address + +A pointer to a string containing the email address. + +=item name + +A pointer to a string containing the name of the person who uses that email +address. + +=back + +=back + +=head2 SDP_GenFromEmailContacts(generator, email_contacts) + + int SDP_GenFromEmailContacts( + SDP_Generator * generator, + SDP_EmailContact * email_contacts + ); + +This function generates "e" fields from each C struct in the +linked list. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "e" fields. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item email_contacts + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GenFromEmailContact(generator, email_contact) + + int SDP_GenFromEmailContact( + SDP_Generator * generator, + SDP_EmailContact * email_contact + ); + +This function generates a single "e" field from a single C +struct. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "e" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item email_contact + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GenPhoneContactField(generator, number, name) + + int SDP_GenPhoneContactField( + SDP_Generator * generator, + const char * number, + const char * name + ); + +This function generates a "p" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "p" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item number + +A pointer to a string containing the phone number. + +=item name + +A pointer to a string containing the name of the person who can be reached at +that phone number. + +=back + +=back + +=head2 SDP_GenFromPhoneContacts(generator, phone_contacts) + + int SDP_GenFromPhoneContacts( + SDP_Generator * generator, + SDP_PhoneContact * phone_contacts + ); + +This function generates "p" fields from every C struct in the +linked list. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "p" fields. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item phone_contacts + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GenFromPhoneContact(generator, phone_contact) + + int SDP_GenFromPhoneContact( + SDP_Generator * generator, + SDP_PhoneContact * phone_contact + ); + +This function generates a "p" field from a single C struct. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "p" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item phone_contact + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GenConnectionField(generator, network_type, address_type, address, ttl, total_addresses) + + int SDP_GenConnectionField( + SDP_Generator * generator, + const char * network_type, + const char * address_type, + const char * address, + int ttl, + int total_addresses + ); + +This function generates a "c" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "c" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item network_type + +A pointer to a string containing the network type (e.g., "IN" for Internet). + +=item address_type + +A pointer to a string containing the address type (e.g., "IP4" for Internet +Protocol version 4). + +=item address + +A pointer to a string containing the address. + +=item ttl + +Time To Live. + +=item total_addresses + +Counting up from "address", how many addresses are there available. + +=back + +=back + +=head2 SDP_GenFromConnection(generator, connection) + + int SDP_GenFromConnection( + SDP_Generator * generator, + SDP_Connection * connection + ); + +This function generates a "c" field from an C struct. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "c" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item connection + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GenBandwidthField(generator, modifier, value) + + int SDP_GenBandwidthField( + SDP_Generator * generator, + const char * modifier, + long value + ); + +This function generates a "b" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "c" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item modifier + +A pointer to a string containing the bandwidth modifier (e.g., "CT" for +Conference Total). + +=item value + +A pointer to a string contianing the bandwidth value. + +=back + +=back + +=head2 SDP_GenFromBandwidth(generator, bandwidth) + + int SDP_GenFromBandwidth( + SDP_Generator * generator, + SDP_Bandwidth * bandwidth + ); + +This function generates a "b" field from an C struct. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "c" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item bandwidth + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GenSessionPlayTimeField(generator, start_time, end_time) + + int SDP_GenSessionPlayTimeField( + SDP_Generator * generator, + time_t start_time, + time_t end_time + ); + +This function generates a "t" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "t" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item start_time + +A C value of when the session starts. + +=item end_time + +A C value of when the session ends. + +=back + +=back + +=head2 SDP_GenFromSessionPlayTimes(generator, session_play_times) + + int SDP_GenFromSessionPlayTimes( + SDP_Generator * generator, + SDP_SessionPlayTime * session_play_times + ); + +This function generates a "t" field and any requisite "r" feilds for each +C struct in the linked list. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "t" fields or "r" fields. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item session_play_times + +A pointer to C struct. + +=back + +=back + +=head2 SDP_GenFromSessionPlayTime(generator, session_play_time) + + int SDP_GenFromSessionPlayTime( + SDP_Generator * generator, + SDP_SessionPlayTime * session_play_time + ); + +This function generates a single "t" field and any requisite "r" fields from +a C struct. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "t" field or "r" fields. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item session_play_time + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GenRepeatTimeField(generator, repeat_interval, active_duration, repeat_offsets) + + int SDP_GenRepeatTimeField( + SDP_Generator * generator, + const char * repeat_interval, + const char * active_duration, + const char * repeat_offsets + ); + +This function generates an "r" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "r" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item repeat_interval + +A pointer to a string containing the repeat interval as a number by itself +(meaning in seconds) or postfixed with the letter "m" (meaning in minutes), "h" +(meaning in hours), or "d" (meaning in days). + +=item active_duration + +A pointer to a string containing the active duration of the session as a number +by itself (meaning in seconds) or postfixed with the letter "m" (meaning in +minutes), "h" (meaning in hours), or "d" (meaning in days). + +=item repeat_offsets + +A string containing one or more repeat offsets seperated by spaces. + +=back + +=back + +=head2 SDP_GenFromRepeatTimes(generator, repeat_times) + + int SDP_GenFromRepeatTimes( + SDP_Generator * generator, + SDP_RepeatTime * repeat_times + ); + +This function generates "r" fields from each C struct in the +linked list. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "r" fields. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item repeat_times + +A pointer to a C struct. + +=back + +=back + +=head2 SDP_GenFromRepeatTime(generator, repeat_time) + + int SDP_GenFromRepeatTime( + SDP_Generator * generator, + SDP_RepeatTime * repeat_time + ); + +This function generates an "r" field from an C struct. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "r" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item repeat_time + +A pointer to the C strcut. + +=back + +=back + +=head2 SDP_GenZoneAdjustmentsField(generator, total_adjustments, ...) + + int SDP_GenZoneAdjustmentsField( + SDP_Generator * generator, + int total_adjustments, + ... + ); + +This function generates a "z" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "z" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item total_adjustments + +The number of time-zone adjustment pairs to expect. + +=item ... + +The remaining arguments come in pairs. The first is the time (as a C +value) of when some type of zone adjustment is to occur. The second is the +adjustment itself in the form of a string comprised of a positive or negative +number followed by a the letter "m" (meaning minutes), "h" (meaning hours), or +"d" (meaning days): + + SDP_GenZoneAdjustmentsField(generator, 2, + some_time, "-1h", + some_other_time, "-2h" + ); + +Each time value will be converted from OS time to Network Protocol Time. + +=back + +=back + +=head2 SDP_GenFromZoneAdjustments(generator, zone_adjustments) + + int SDP_GenFromZoneAdjustments( + SDP_Generator * generator, + SDP_ZoneAdjustment * zone_adjustments + ); + +Stub description documentation. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "z" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item zone_adjustments + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GenEncryptionField(generator, method, key) + + int SDP_GenEncryptionField( + SDP_Generator * generator, + const char * method, + const char * key + ); + +This function generates a "k" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "e" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item method + +A pointer to a string containing the encryption method. + +=item key + +A pointer to a string containing the encyption key. + +=back + +=back + +=head2 SDP_GenFromEncryption(generator, encryption) + + int SDP_GenFromEncryption( + SDP_Generator * generator, + SDP_Encryption * encryption + ); + +This function generates a "k" field from an C struct. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "k" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item encryption + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GenAttributeField(generator, name, value) + + int SDP_GenAttributeField( + SDP_Generator * generator, + const char * name, + const char * value + ); + +This function generates an "a" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "a" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item name + +A pointer to a string containing the name of the attribute. + +=item value + +A pointer to a string containing the value of the attribute. + +=back + +=back + +=head2 SDP_GenFromAttributes(generator, attributes) + + int SDP_GenFromAttributes( + SDP_Generator * generator, + SDP_Attribute * attributes + ); + +This function generates "a" fields from every C struct in the +linked list. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "a" fields. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item attributes + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GenFromAttribute(generator, attribute) + + int SDP_GenFromAttribute( + SDP_Generator * generator, + SDP_Attribute * attribute + ); + +This function generates an "a" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "a" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item attribute + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GenMediaDescriptionField(generator, media_type, port, total_ports, transport_protocol, formats) + + int SDP_GenMediaDescriptionField( + SDP_Generator * generator, + const char * media_type, + const char * port, + const char * transport_protocol, + const char * formats + ); + +This function generates an "m" field. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "m" field. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item media_type + +A pointer to a string containing the media type. + +=item port + +A pointer to a string containing the port number with an optional number of +other usable ports for UDP multicasts. + +=item transport_protocol + +A pointer to a string containing the transport protocol (e.g., "RTP/AVP"). + +=item formats + +A pointer to a string containing media formats separated by spaces. + +=back + +=back + +=head2 SDP_GenFromMediaDescriptions(generator, media_descriptions) + + int SDP_GenFromMediaDescriptions( + SDP_Generator * generator, + SDP_MediaDescription * media_descriptions + ); + +This function generates "m" fields and any other requisite fields from each +C in the linked list. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There isn't enough memory available to + generate the "m" fields. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item media_descriptions + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GenFromMediaDescription(generator, media_description) + + int SDP_GenFromMediaDescription( + SDP_Generator * generator, + SDP_MediaDescription * media_description + ); + +This function generates an "m" field and any related fields from an +C struct. + +=over 4 + +=item Return Value + +Stub return value documentation. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item media_description + +A pointer to an C struct. + +=back + +=back + +=head2 SDP_GetGeneratedOutput(generator) + + char *SDP_GetGeneratedOutput(SDP_Generator *generator); + +This function returns a pointer to the generator's buffer. If you want to +modify the this or use it after calling C, use +C or some comparable function to copy it. + +=over 4 + +=item Return Value + +A pointer to the generator's output buffer. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_SaveGeneratedOutput(generator, filename) + + int SDP_SaveGeneratedOutput( + SDP_Generator * generator, + const char * filename + ); + +This function outputs the generator buffer to a file. If the file specified +doesn't already exist, then it will be created. If it does exist, then anything +in it will be overwritten. + +=over 4 + +=item Return Value + +It returns ture if no error occurs, false otherwise. Call C +for extended error information. The possible error codes returned are: + + SDP_ERR_FILE_OPEN_FAILED - The file you specified could not + be opened. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct. + +=item filename + +A pointer to a string containing the name of the file to write to. + +=back + +=back + +=head2 SDP_DestroyGenerator(generator) + + void SDP_DestroyGenerator(SDP_Generator *generator); + +This function destroys an SDP generator, returning its memory to the system. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item generator + +A pointer to the C struct to destroy. + +=back + +=back + +=head1 BUGS + +Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse + +You can also email me directly: +. + +=head1 COPYRIGHT + +Copyright 2004 by William G. Davis. + +This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. + +=cut + diff --git a/src/sdp_lib/SinisterSdpParser.html b/src/sdp_lib/SinisterSdpParser.html new file mode 100644 index 0000000..fa00391 --- /dev/null +++ b/src/sdp_lib/SinisterSdpParser.html @@ -0,0 +1,834 @@ + + + + +SinisterSdpParser.pod + + + + + + +
+

NAME

+ +

SinisterSdpParser - The SDP parser routines

+

SYNOPSIS

+ +
 #include <SDP/SDP_Parser.h>
+ 
+ int main(void)
+ {
+ 	SDP_Parser *parser;
+ 	SDP_Description *description;
+ 
+ 	parser = SDP_NewParser();
+ 	description = SDP_ParseFile(parser, 'description.sdp');
+ 
+	...
+ }
+
+
+

DESCRIPTION

+ +

The SinisterSdp parser is a standards compliant (RFC 2327) SDP parser that can +parse SDP descriptions from multiple types of sreams. The parsed descriptions +and their fields are encapsulated by structures and functions that operate on +them, which are described in +SinisterSdpDescriptions.html.

+

The parser performs some basic validation on the descriptions it parses, +ensuring required sub fields are present, for example, or that the fields are +not horribly out of order. These non fatal parser errors can be caught and +handled dynamically using a non-fatal error handler as described in +SinisterSdpError.html.

+

Also exposed here in the API is the lower-level event stream parser. This +simple parser alows you to register handlers for certain events (like +encountering the start of a description, encountering a field, encountering the +end of a description) and build your own custom SDP parser.

+

FUNCTIONS

+ +

The following functions are available:

+

SDP_NewParser()

+ +
 SDP_Parser *SDP_NewParser(void);
+
+
+

This function creates a new SDP_Parser struct. All of the other parser +functions take a pointer to this struct as their first argument.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the newly created +SDP_Parser struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call SDP_GetLastError(). The +possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to 
    +                         create the SDP_Parser struct.
    +
    +
    +
  • Parameters
  • +

    None.

    +
+

SDP_Parse(parser, string)

+ +
 SDP_Description *SDP_Parse(
+ 	SDP_Parser *   parser,
+ 	const char *   string
+ );
+
+
+

This function parses one or more SDP session descriptions from a string into +a linked list of SDP_Description stucts, each of which encapsulate a single +session description.

+

You can retrieve and modify the various parts of the description encapsulated +by an SDP_Description struct with the routines outlined in +SinisterSdpDescriptions.html.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the first and probably only +SDP_Description struct in the linked list. If an error occurs, it returns a +NULL pointer instead. For extended error information call +SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY          = There's not enough memory available
    +                                  to parse the description(s).
    + SDP_ERR_MALFORMED_LINE         = A line wasn't in the proper
    +                                  "x=value" format.
    + SDP_ERR_MALFORMED_V_FIELD      = The "v" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_O_FIELD      = The "o" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_E_FIELD      = An "e" field was malformed and
    +                                  could not be parsed. 
    + SDP_ERR_MALFORMED_P_FIELD      = A "p" field was malformed and could
    +                                  not be parsed.
    + SDP_ERR_MALFORMED_C_FIELD      = A "c" field was malformed and could
    +                                  not be parsed.
    + SDP_ERR_MALFORMED_B_FIELD      = A "b" field was malformed and could
    +                                  not be parsed.
    + SDP_ERR_MALFORMED_T_FIELD      = The "t" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_R_FIELD      = An "r" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_Z_FIELD      = The "z" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_K_FIELD      = A "k" field was malformed and could
    +                                  not be parsed.
    + SDP_ERR_MALFORMED_A_FIELD      = An "a" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_M_FIELD      = An "m" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_INVALID_TYPE_CHARACTER = A field was encountered with an
    +                                  unknown type character.
    + SDP_ERR_MULTIPLE_UNIQUE_FIELDS = A unique field (e.g., "o") was
    +                                  encountered more than once in a
    +                                  single session description.
    + SDP_ERR_FIELDS_OUT_OF_SEQUENCE = Some fields were out of sequence
    +                                  (e.g., a "r" field before its "t"
    +				  field).
    +
    +
    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • string
    • +

      A pointer to the string to parse.

      +
    +
+

SDP_ParseFile(parser, filename)

+ +
 SDP_Description *SDP_Parse(
+ 	SDP_Parser *   parser,
+ 	const char *   filename
+ );
+
+
+

This function parses one or more SDP session descriptions from a file into +a linked list of SDP_Description stucts, each of which encapsulate a single +session description.

+

You can retrieve and modify the various parts of the description encapsulated +by an SDP_Description struct with the routines outlined in +SinisterSdpDescriptions.

+
    +
  • Return Value
  • +

    If no error occurs, it returns a pointer to the first and probably only +SDP_Description struct in the linked list. If an error occurs, it returns a +NULL pointer instead. For extended error information call +SDP_GetLastError(). The possible error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY          = There's not enough memory available
    +                                  to parse the description(s).
    + SDP_ERR_FILE_OPEN_FAILED       = Couldn't open the file you
    +                                  specified.
    + SDP_ERR_MALFORMED_LINE         = A line wasn't in the proper
    +                                  "x=value" format.
    + SDP_ERR_MALFORMED_V_FIELD      = The "v" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_O_FIELD      = The "o" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_E_FIELD      = An "e" field was malformed and
    +                                  could not be parsed. 
    + SDP_ERR_MALFORMED_P_FIELD      = A "p" field was malformed and could
    +                                  not be parsed.
    + SDP_ERR_MALFORMED_C_FIELD      = A "c" field was malformed and could
    +                                  not be parsed.
    + SDP_ERR_MALFORMED_B_FIELD      = A "b" field was malformed and could
    +                                  not be parsed.
    + SDP_ERR_MALFORMED_T_FIELD      = The "t" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_R_FIELD      = An "r" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_Z_FIELD      = The "z" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_K_FIELD      = A "k" field was malformed and could
    +                                  not be parsed.
    + SDP_ERR_MALFORMED_A_FIELD      = An "a" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_MALFORMED_M_FIELD      = An "m" field was malformed and
    +                                  could not be parsed.
    + SDP_ERR_INVALID_TYPE_CHARACTER = A field was encountered with an
    +                                  unknown type character.
    + SDP_ERR_MULTIPLE_UNIQUE_FIELDS = A unique field (e.g., "o") was
    +                                  encountered more than once in a
    +                                  single session description.
    + SDP_ERR_FIELDS_OUT_OF_SEQUENCE = Some fields were out of sequence
    +                                  (e.g., a "r" field before its "t"
    +				  field).
    +
    +
    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • filename
    • +

      A pointer to a string containing the name of the file to parse.

      +
    +
+

SDP_DestroyParser(parser)

+ +
 void SDP_Parse(SDP_Parser *parser);
+
+
+

This function destroys an SDP_Parser struct, freeing any memory associated +with it. Call this when you are finished with it and don't need to do any more +parsing.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_EventStreamParse(parser, string)

+ +
 int SDP_EventStreamParse(
+ 	SDP_Parser *   parser,
+ 	const char *   string
+ );
+
+
+

This function provides access to the lower-level event stream parser. It parses +the string as an event stream and calls various event handlers as it goes. It +also passes on a pointer to some piece of data if you supply one.

+

The handlers you can register are:

+
 1) a start handler to be invoked before the parser starts parsing;
+
+ 2) a start-of-description handler to be invoked when the current field
+    denotes the start of an SDP description (a "v" field);
+ 
+ 3) a field handler to be invoked for each field;
+
+ 4) an end-of-description handler to be invoked when the current field
+    denotes the end of a description (a subsequint "v" field or the end
+    of the stream);
+
+ 5) and then an end handler to be invoked when it stops parsing.
+
+
+

The end handler (if registered) will be invoked when parsing stops regardless +of whether or not it stops after successfully parsing the stream or stops +because of an error (this is to enable you to do any neccessary cleanup). As +a convience, the return value detailed below will also be passed on to the +end handler.

+

You can register a non-fatal error handler to catch parser errors and decide +dynamically whether or not you want it to keep parsing. See +SinisterSdpErrorHandling for more information on this.

+
    +
  • Return Value
  • +

    This function returns true if it is able to successfully parse the string, +false otherwise. Call SDP_GetLastError() for extened error information. +Among the error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY          = There's not enough memory available
    +                                  to parse the fields.
    + SDP_ERR_MALFORMED_LINE         = A line wasn't in the proper
    +                                  "x=value" format.
    + SDP_ERR_INVALID_TYPE_CHARACTER = A field was encountered with an
    +                                  unknown type character.
    + SDP_ERR_MULTIPLE_UNIQUE_FIELDS = A unique field (e.g., "o") was
    +                                  encountered more than once in a
    +                                  single session description.
    + SDP_ERR_FEILDS_OUT_OF_SEQUENCE = Some fields were out of sequence
    +                                  (e.g., a "r" field before its "t"
    +				  field).
    +
    +
    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • string
    • +

      A pointer to the string to parse.

      +
    +
+

SDP_EventStreamParseFile(parser, filename)

+ +
 int SDP_EventStreamParseFile(
+ 	SDP_Parser *   parser,
+ 	const char *   filename
+ );
+
+
+

This function works just like SDP_EventStreamParse except instead of a +string to parse, it takes the name of a file, opens it, and then parses the +file as an event stream.

+
    +
  • Return Value
  • +

    This function returns true if it is able to successfully parse the file, +false otherwise. Call SDP_GetLastError() for extened error information. +Among the error codes returned are:

    +
     SDP_ERR_OUT_OF_MEMORY          = There's not enough memory available
    +                                  to parse the fields.
    + SDP_ERR_FILE_OPEN_FAILED       = Couldn't open the file you
    +                                  specified.
    + SDP_ERR_MALFORMED_LINE         = A line wasn't in the proper
    +                                  "x=value" format.
    + SDP_ERR_INVALID_TYPE_CHARACTER = A field was encountered with an
    +                                  unknown type character.
    + SDP_ERR_MULTIPLE_UNIQUE_FIELDS = A unique field (e.g., "o") was
    +                                  encountered more than once in a
    +                                  single session description.
    + SDP_ERR_FEILDS_OUT_OF_SEQUENCE = Some fields were out of sequence
    +                                  (e.g., a "r" field before its "t"
    +				  field).
    +
    +
    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • filename
    • +

      A pointer to a string containing the name of the file to parse.

      +
    +
+

SDP_SetStartHandler(parser, handler)

+ +
 void SDP_SetStartHandler(
+ 	SDP_Parser *       parser,
+ 	SDP_StartHandler   handler
+ );
+
+
+

This function registers a start handler to be invoked when parsing starts.

+

Here is a prototype for a sample handler:

+
 int sample_start_handler(
+ 	SDP_Parser *   parser,
+ 	void *         user_data
+ );
+
+
+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • handler
    • +

      A pointer to the start handler function to register.

      +
    +
+

SDP_SetStartDescriptionHandler(parser, handler)

+ +
 void SDP_SetStartDescriptionHandler(
+ 	SDP_Parser *                  parser,
+ 	SDP_StartDescriptionHandler   handler
+ );
+
+
+

This function registers a start-of-description handler to be invoked when a +"v" field is encoutered (designating the start of a new description).

+

Here is the prototype for a sample handler:

+
 int sample_start_of_description_handler(
+ 	SDP_Parser *   parser,
+ 	int            current_description_number,
+ 	void *         user_data
+ );
+
+
+

The second argument passed to the handler is the number of the description +(e.g., 1 for the first description encountered, 2 for the second, 3 for the +third, etc.)

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • handler
    • +

      A pointer to the start of description handler function to register.

      +
    +
+

SDP_SetFieldHandler(parser, handler)

+ +
 void SDP_SetFieldHandler(
+ 	SDP_Parser *       parser,
+ 	SDP_FieldHandler   handler
+ );
+
+
+

This function registers a field handler to be invoked for each SDP field +encountered.

+

Here is the prototype of a sample handler:

+
 int sample_field_handler(
+ 	SDP_Parser *   parser,
+ 	char           type,
+ 	const char *   value,
+ 	void *         user_data
+ );
+
+
+

The second argument passed in is the type character for the field (e.g., "v", +"o", "t", "r", "m"). The third is a pointer to a string containing the field's +value.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • handler
    • +

      A pointer to the field handler function to register.

      +
    +
+

SDP_SetEndDescriptionHandler(parser, handler)

+ +
 void SDP_SetEndDescriptionHandler(
+ 	SDP_Parser *                parser,
+ 	SDP_EndDescriptionHandler   handler
+ );
+
+
+

This function registers an end-of-description handler to be invoked when the +end of an SDP description is encountered (either by reaching the end of the +stream or by encountering another "v" field, which denotes the start of the +next description).

+

Here is the prototype for a sample handler:

+
 int sample_end_description_handler(
+ 	struct _SDP_Parser *   parser,
+ 	int                    current_description_number,
+ 	void *                 user_data
+ );
+
+
+

The second argument passed in is the same as that for the start-of-description +handler, the number of the current description.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • handler
    • +

      A pointer to the end-of-description handler function to register.

      +
    +
+

SDP_SetEndHandler(parser, handler)

+ +
 void SDP_SetEndHandler(
+ 	SDP_Parser *     parser,
+ 	SDP_EndHandler   handler
+ );
+
+
+

This function registers an end handler to be invoked when parsing stops.

+

Here is the prototype of a sample handler:

+
 void sample_end_handler(
+ 	SDP_Parser *   parser,
+ 	int            result,
+ 	void *         user_data
+ );
+
+
+

The second argument passed in is same thing returned by either of the +SDP_EventStreamParse() or SDP_EventStreamParseFile() functions, the +result of parsing, true or false indicating success or failure.

+

Note the "void" return type.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • handler
    • +

      A pointer to the end handler function to register.

      +
    +
+

SDP_SetUserData(parser, user_data)

+ +
 void SDP_SetUserData(
+ 	SDP_Parser *   parser,
+ 	void *         user_data
+ );
+
+
+

This function takes a pointer to some piece of data you want each of the above +mentioned handlers to get passed.

+
    +
  • Return Value
  • +

    None.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • user_data
    • +

      A pointer to some piece of data.

      +
    +
+

SDP_GetStartHandler(parser)

+ +
 SDP_StartHandler SDP_GetStartHandler(SDP_Parser *parser);
+
+
+

This function retrieves the current start handler.

+
    +
  • Return Value
  • +

    If a start handler function was register, then it returns a pointer to it. +Otherwise, a NULL pointer is returned instead.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_GetStartDescriptionHandler(parser)

+ +
 SDP_StartDescriptionHandler SDP_GetStartDescriptionHandler(
+ 	SDP_Parser *parser
+ );
+
+
+

This function retrieves the current start-of-description handler.

+
    +
  • Return Value
  • +

    If a start-of-description handler function was register, then it returns a +pointer to it. Otherwise, a NULL pointer is returned instead.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_GetFieldHandler(parser)

+ +
 SDP_FieldHandler SDP_GetFieldHandler(SDP_Parser *parser);
+
+
+

This function retrieves the curreent field handler.

+
    +
  • Return Value
  • +

    If a field handler function was register, then it returns a pointer to it. +Otherwise, a NULL pointer is returned instead.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_GetEndDescriptionHandler(parser)

+ +
 SDP_EndDescriptionHandler SDP_GetEndDescriptionHandler(SDP_Parser *parser);
+
+
+

This function retrieves the current end-of-description handler.

+
    +
  • Return Value
  • +

    If an end-of-description handler function was register, then it returns a +pointer to it. Otherwise, a NULL pointer is returned instead.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_GetEndHandler(parser)

+ +
 SDP_EndHandler SDP_GetEndHandler(SDP_Parser *parser);
+
+
+

This function retrieves the current end handler.

+
    +
  • Return Value
  • +

    If an end-of-description handler function was register, then it returns a +pointer to it. Otherwise, a NULL pointer is returned instead.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_GetUserData(parser)

+ +
 void *SDP_GetUserData(SDP_Parser *parser);
+
+
+

This function retrieves your current user data.

+
    +
  • Return Value
  • +

    A pointer to the piece of data or NULL if there is none.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_GetCurrentLineNumber(parser)

+ +
 int SDP_GetCurrentLineNumber(SDP_Parser *parser);
+
+
+

This function returns the number of the current line in the stream being parsed +(for example, 1 for the first line, 2 for the second, etc.).

+
    +
  • Return Value
  • +

    The line number.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_GetCurrentDescriptionNumber(parser)

+ +
 int SDP_GetCurrentDescriptionNumber(SDP_Parser *parser);
+
+
+

This function returns the number of the current description being parsed (e.g., +1 for the first description, 2 for the second, etc.).

+
    +
  • Return Value
  • +

    The description number.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_GetCurrentFieldType(parser)

+ +
 char SDP_GetCurrentFieldType(SDP_Parser *parser);
+
+
+

This function returns the character of the current SDP field (for example, "v", +"o", "t", "r", "m", etc.).

+
    +
  • Return Value
  • +

    The field type character.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_GetCurrentField(parser)

+ +
 char *SDP_GetCurrentField(SDP_Parser *parser);
+
+
+

This function retrieves the current field value.

+
    +
  • Return Value
  • +

    A pointer to a string containing the current field value.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    +
+

SDP_FieldEncountered(parser, field_type)

+ +
 int SDP_FieldEncountered(
+ 	SDP_Parser *   parser,
+ 	char           field_type
+ );
+
+
+

This function can be used to tell you if a particular field has been +encountered yet for the current description being parsed.

+
    +
  • Return Value
  • +

    The number of times the field has been encountered.

    +
  • Parameters
  • +
      +
    • parser
    • +

      A pointer to the SDP_Parser struct.

      +
    • field_type
    • +

      The field type character.

      +
    +
+

BUGS

+ +

Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse

+

You can also email me directly: +<william_g_davis at users dot sourceforge dot net>.

+

COPYRIGHT

+ +

Copyright 2004 by William G. Davis.

+

This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution.

+

This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE.

+ + +
diff --git a/src/sdp_lib/SinisterSdpParser.pod b/src/sdp_lib/SinisterSdpParser.pod new file mode 100644 index 0000000..2a8a4e1 --- /dev/null +++ b/src/sdp_lib/SinisterSdpParser.pod @@ -0,0 +1,925 @@ +=head1 NAME + +SinisterSdpParser - The SDP parser routines + +=head1 SYNOPSIS + + #include + + int main(void) + { + SDP_Parser *parser; + SDP_Description *description; + + parser = SDP_NewParser(); + description = SDP_ParseFile(parser, 'description.sdp'); + + ... + } + +=head1 DESCRIPTION + +The SinisterSdp parser is a standards compliant (RFC 2327) SDP parser that can +parse SDP descriptions from multiple types of sreams. The parsed descriptions +and their fields are encapsulated by structures and functions that operate on +them, which are described in +L. + +The parser performs some basic validation on the descriptions it parses, +ensuring required sub fields are present, for example, or that the fields are +not horribly out of order. These non fatal parser errors can be caught and +handled dynamically using a non-fatal error handler as described in +L. + +Also exposed here in the API is the lower-level event stream parser. This +simple parser alows you to register handlers for certain events (like +encountering the start of a description, encountering a field, encountering the +end of a description) and build your own custom SDP parser. + +=head1 FUNCTIONS + +The following functions are available: + +=head2 SDP_NewParser() + + SDP_Parser *SDP_NewParser(void); + +This function creates a new C struct. All of the other parser +functions take a pointer to this struct as their first argument. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the newly created +C struct. If an error occurs, it returns a NULL pointer +instead. For extended error information call C. The +possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY - There's not enough memory available to + create the SDP_Parser struct. + +=item Parameters + +None. + +=back + +=head2 SDP_Parse(parser, string) + + SDP_Description *SDP_Parse( + SDP_Parser * parser, + const char * string + ); + +This function parses one or more SDP session descriptions from a string into +a linked list of C stucts, each of which encapsulate a single +session description. + +You can retrieve and modify the various parts of the description encapsulated +by an C struct with the routines outlined in +L. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the first and probably only +C struct in the linked list. If an error occurs, it returns a +NULL pointer instead. For extended error information call +C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY = There's not enough memory available + to parse the description(s). + SDP_ERR_MALFORMED_LINE = A line wasn't in the proper + "x=value" format. + SDP_ERR_MALFORMED_V_FIELD = The "v" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_O_FIELD = The "o" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_E_FIELD = An "e" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_P_FIELD = A "p" field was malformed and could + not be parsed. + SDP_ERR_MALFORMED_C_FIELD = A "c" field was malformed and could + not be parsed. + SDP_ERR_MALFORMED_B_FIELD = A "b" field was malformed and could + not be parsed. + SDP_ERR_MALFORMED_T_FIELD = The "t" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_R_FIELD = An "r" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_Z_FIELD = The "z" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_K_FIELD = A "k" field was malformed and could + not be parsed. + SDP_ERR_MALFORMED_A_FIELD = An "a" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_M_FIELD = An "m" field was malformed and + could not be parsed. + SDP_ERR_INVALID_TYPE_CHARACTER = A field was encountered with an + unknown type character. + SDP_ERR_MULTIPLE_UNIQUE_FIELDS = A unique field (e.g., "o") was + encountered more than once in a + single session description. + SDP_ERR_FIELDS_OUT_OF_SEQUENCE = Some fields were out of sequence + (e.g., a "r" field before its "t" + field). + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item string + +A pointer to the string to parse. + +=back + +=back + +=head2 SDP_ParseFile(parser, filename) + + SDP_Description *SDP_Parse( + SDP_Parser * parser, + const char * filename + ); + +This function parses one or more SDP session descriptions from a file into +a linked list of C stucts, each of which encapsulate a single +session description. + +You can retrieve and modify the various parts of the description encapsulated +by an C struct with the routines outlined in +L. + +=over 4 + +=item Return Value + +If no error occurs, it returns a pointer to the first and probably only +C struct in the linked list. If an error occurs, it returns a +NULL pointer instead. For extended error information call +C. The possible error codes returned are: + + SDP_ERR_OUT_OF_MEMORY = There's not enough memory available + to parse the description(s). + SDP_ERR_FILE_OPEN_FAILED = Couldn't open the file you + specified. + SDP_ERR_MALFORMED_LINE = A line wasn't in the proper + "x=value" format. + SDP_ERR_MALFORMED_V_FIELD = The "v" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_O_FIELD = The "o" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_E_FIELD = An "e" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_P_FIELD = A "p" field was malformed and could + not be parsed. + SDP_ERR_MALFORMED_C_FIELD = A "c" field was malformed and could + not be parsed. + SDP_ERR_MALFORMED_B_FIELD = A "b" field was malformed and could + not be parsed. + SDP_ERR_MALFORMED_T_FIELD = The "t" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_R_FIELD = An "r" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_Z_FIELD = The "z" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_K_FIELD = A "k" field was malformed and could + not be parsed. + SDP_ERR_MALFORMED_A_FIELD = An "a" field was malformed and + could not be parsed. + SDP_ERR_MALFORMED_M_FIELD = An "m" field was malformed and + could not be parsed. + SDP_ERR_INVALID_TYPE_CHARACTER = A field was encountered with an + unknown type character. + SDP_ERR_MULTIPLE_UNIQUE_FIELDS = A unique field (e.g., "o") was + encountered more than once in a + single session description. + SDP_ERR_FIELDS_OUT_OF_SEQUENCE = Some fields were out of sequence + (e.g., a "r" field before its "t" + field). + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item filename + +A pointer to a string containing the name of the file to parse. + +=back + +=back + +=head2 SDP_DestroyParser(parser) + + void SDP_Parse(SDP_Parser *parser); + +This function destroys an C struct, freeing any memory associated +with it. Call this when you are finished with it and don't need to do any more +parsing. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_EventStreamParse(parser, string) + + int SDP_EventStreamParse( + SDP_Parser * parser, + const char * string + ); + +This function provides access to the lower-level event stream parser. It parses +the string as an event stream and calls various event handlers as it goes. It +also passes on a pointer to some piece of data if you supply one. + +The handlers you can register are: + + 1) a start handler to be invoked before the parser starts parsing; + + 2) a start-of-description handler to be invoked when the current field + denotes the start of an SDP description (a "v" field); + + 3) a field handler to be invoked for each field; + + 4) an end-of-description handler to be invoked when the current field + denotes the end of a description (a subsequint "v" field or the end + of the stream); + + 5) and then an end handler to be invoked when it stops parsing. + +The end handler (if registered) will be invoked when parsing stops regardless +of whether or not it stops after successfully parsing the stream or stops +because of an error (this is to enable you to do any neccessary cleanup). As +a convience, the return value detailed below will also be passed on to the +end handler. + +You can register a non-fatal error handler to catch parser errors and decide +dynamically whether or not you want it to keep parsing. See +L for more information on this. + +=over 4 + +=item Return Value + +This function returns true if it is able to successfully parse the string, +false otherwise. Call C for extened error information. +Among the error codes returned are: + + SDP_ERR_OUT_OF_MEMORY = There's not enough memory available + to parse the fields. + SDP_ERR_MALFORMED_LINE = A line wasn't in the proper + "x=value" format. + SDP_ERR_INVALID_TYPE_CHARACTER = A field was encountered with an + unknown type character. + SDP_ERR_MULTIPLE_UNIQUE_FIELDS = A unique field (e.g., "o") was + encountered more than once in a + single session description. + SDP_ERR_FEILDS_OUT_OF_SEQUENCE = Some fields were out of sequence + (e.g., a "r" field before its "t" + field). + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item string + +A pointer to the string to parse. + +=back + +=back + +=head2 SDP_EventStreamParseFile(parser, filename) + + int SDP_EventStreamParseFile( + SDP_Parser * parser, + const char * filename + ); + +This function works just like C except instead of a +string to parse, it takes the name of a file, opens it, and then parses the +file as an event stream. + +=over 4 + +=item Return Value + +This function returns true if it is able to successfully parse the file, +false otherwise. Call C for extened error information. +Among the error codes returned are: + + SDP_ERR_OUT_OF_MEMORY = There's not enough memory available + to parse the fields. + SDP_ERR_FILE_OPEN_FAILED = Couldn't open the file you + specified. + SDP_ERR_MALFORMED_LINE = A line wasn't in the proper + "x=value" format. + SDP_ERR_INVALID_TYPE_CHARACTER = A field was encountered with an + unknown type character. + SDP_ERR_MULTIPLE_UNIQUE_FIELDS = A unique field (e.g., "o") was + encountered more than once in a + single session description. + SDP_ERR_FEILDS_OUT_OF_SEQUENCE = Some fields were out of sequence + (e.g., a "r" field before its "t" + field). + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item filename + +A pointer to a string containing the name of the file to parse. + +=back + +=back + +=head2 SDP_SetStartHandler(parser, handler) + + void SDP_SetStartHandler( + SDP_Parser * parser, + SDP_StartHandler handler + ); + +This function registers a start handler to be invoked when parsing starts. + +Here is a prototype for a sample handler: + + int sample_start_handler( + SDP_Parser * parser, + void * user_data + ); + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item handler + +A pointer to the start handler function to register. + +=back + +=back + +=head2 SDP_SetStartDescriptionHandler(parser, handler) + + void SDP_SetStartDescriptionHandler( + SDP_Parser * parser, + SDP_StartDescriptionHandler handler + ); + +This function registers a start-of-description handler to be invoked when a +"v" field is encoutered (designating the start of a new description). + +Here is the prototype for a sample handler: + + int sample_start_of_description_handler( + SDP_Parser * parser, + int current_description_number, + void * user_data + ); + +The second argument passed to the handler is the number of the description +(e.g., 1 for the first description encountered, 2 for the second, 3 for the +third, etc.) + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item handler + +A pointer to the start of description handler function to register. + +=back + +=back + +=head2 SDP_SetFieldHandler(parser, handler) + + void SDP_SetFieldHandler( + SDP_Parser * parser, + SDP_FieldHandler handler + ); + +This function registers a field handler to be invoked for each SDP field +encountered. + +Here is the prototype of a sample handler: + + int sample_field_handler( + SDP_Parser * parser, + char type, + const char * value, + void * user_data + ); + +The second argument passed in is the type character for the field (e.g., "v", +"o", "t", "r", "m"). The third is a pointer to a string containing the field's +value. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item handler + +A pointer to the field handler function to register. + +=back + +=back + +=head2 SDP_SetEndDescriptionHandler(parser, handler) + + void SDP_SetEndDescriptionHandler( + SDP_Parser * parser, + SDP_EndDescriptionHandler handler + ); + +This function registers an end-of-description handler to be invoked when the +end of an SDP description is encountered (either by reaching the end of the +stream or by encountering another "v" field, which denotes the start of the +next description). + +Here is the prototype for a sample handler: + + int sample_end_description_handler( + struct _SDP_Parser * parser, + int current_description_number, + void * user_data + ); + +The second argument passed in is the same as that for the start-of-description +handler, the number of the current description. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item handler + +A pointer to the end-of-description handler function to register. + +=back + +=back + +=head2 SDP_SetEndHandler(parser, handler) + + void SDP_SetEndHandler( + SDP_Parser * parser, + SDP_EndHandler handler + ); + +This function registers an end handler to be invoked when parsing stops. + +Here is the prototype of a sample handler: + + void sample_end_handler( + SDP_Parser * parser, + int result, + void * user_data + ); + +The second argument passed in is same thing returned by either of the +C or C functions, the +result of parsing, true or false indicating success or failure. + +Note the "void" return type. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item handler + +A pointer to the end handler function to register. + +=back + +=back + +=head2 SDP_SetUserData(parser, user_data) + + void SDP_SetUserData( + SDP_Parser * parser, + void * user_data + ); + +This function takes a pointer to some piece of data you want each of the above +mentioned handlers to get passed. + +=over 4 + +=item Return Value + +None. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item user_data + +A pointer to some piece of data. + +=back + +=back + +=head2 SDP_GetStartHandler(parser) + + SDP_StartHandler SDP_GetStartHandler(SDP_Parser *parser); + +This function retrieves the current start handler. + +=over 4 + +=item Return Value + +If a start handler function was register, then it returns a pointer to it. +Otherwise, a NULL pointer is returned instead. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GetStartDescriptionHandler(parser) + + SDP_StartDescriptionHandler SDP_GetStartDescriptionHandler( + SDP_Parser *parser + ); + +This function retrieves the current start-of-description handler. + +=over 4 + +=item Return Value + +If a start-of-description handler function was register, then it returns a +pointer to it. Otherwise, a NULL pointer is returned instead. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GetFieldHandler(parser) + + SDP_FieldHandler SDP_GetFieldHandler(SDP_Parser *parser); + +This function retrieves the curreent field handler. + +=over 4 + +=item Return Value + +If a field handler function was register, then it returns a pointer to it. +Otherwise, a NULL pointer is returned instead. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GetEndDescriptionHandler(parser) + + SDP_EndDescriptionHandler SDP_GetEndDescriptionHandler(SDP_Parser *parser); + +This function retrieves the current end-of-description handler. + +=over 4 + +=item Return Value + +If an end-of-description handler function was register, then it returns a +pointer to it. Otherwise, a NULL pointer is returned instead. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GetEndHandler(parser) + + SDP_EndHandler SDP_GetEndHandler(SDP_Parser *parser); + +This function retrieves the current end handler. + +=over 4 + +=item Return Value + +If an end-of-description handler function was register, then it returns a +pointer to it. Otherwise, a NULL pointer is returned instead. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GetUserData(parser) + + void *SDP_GetUserData(SDP_Parser *parser); + +This function retrieves your current user data. + +=over 4 + +=item Return Value + +A pointer to the piece of data or NULL if there is none. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GetCurrentLineNumber(parser) + + int SDP_GetCurrentLineNumber(SDP_Parser *parser); + +This function returns the number of the current line in the stream being parsed +(for example, 1 for the first line, 2 for the second, etc.). + +=over 4 + +=item Return Value + +The line number. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GetCurrentDescriptionNumber(parser) + + int SDP_GetCurrentDescriptionNumber(SDP_Parser *parser); + +This function returns the number of the current description being parsed (e.g., +1 for the first description, 2 for the second, etc.). + +=over 4 + +=item Return Value + +The description number. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GetCurrentFieldType(parser) + + char SDP_GetCurrentFieldType(SDP_Parser *parser); + +This function returns the character of the current SDP field (for example, "v", +"o", "t", "r", "m", etc.). + +=over 4 + +=item Return Value + +The field type character. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_GetCurrentField(parser) + + char *SDP_GetCurrentField(SDP_Parser *parser); + +This function retrieves the current field value. + +=over 4 + +=item Return Value + +A pointer to a string containing the current field value. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=back + +=back + +=head2 SDP_FieldEncountered(parser, field_type) + + int SDP_FieldEncountered( + SDP_Parser * parser, + char field_type + ); + +This function can be used to tell you if a particular field has been +encountered yet for the current description being parsed. + +=over 4 + +=item Return Value + +The number of times the field has been encountered. + +=item Parameters + +=over 4 + +=item parser + +A pointer to the C struct. + +=item field_type + +The field type character. + +=back + +=back + +=head1 BUGS + +Bugs in this package can be reported and monitored using sourceforge.net: +http://sourceforge.net/tracker/?atid=644250&group_id=106387&func=browse + +You can also email me directly: +. + +=head1 COPYRIGHT + +Copyright 2004 by William G. Davis. + +This library is free software released under the terms of the GNU Lesser +General Public License (LGPL), the full terms of which can be found in the +"COPYING" file that comes with the distribution. + +This library is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. + +=cut + diff --git a/src/sdp_lib/sdplib.vcproj b/src/sdp_lib/sdplib.vcproj new file mode 100755 index 0000000..a09adae --- /dev/null +++ b/src/sdp_lib/sdplib.vcproj @@ -0,0 +1,153 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/sdp_lib/src/Makefile b/src/sdp_lib/src/Makefile new file mode 100644 index 0000000..199c26b --- /dev/null +++ b/src/sdp_lib/src/Makefile @@ -0,0 +1,132 @@ +####### OS Dependant Definitions ###### + +# they are defined in the following file... +# edit Rules.make as appropriate +include ../../../Makefile.common + + +# libraries required +ifeq (${OS},linux) + # Linux version + # + BINDIR = ../../../bin/linux +endif + +ifeq (${OS},solaris) + # Solaris version: + # Warning: SUN recommends to have -lucb at the end of list, + # in order to priviledge SUN's libs to the BSD compatibility + # lib (libucb). + # CC requires: -mt -lpthread for multithreaded applications + # OpenSSL is installed at /usr/local/ssl in our system. Update if + # needed. + # + BINDIR = ../../../bin/solaris +endif + +ifeq (${OS},freebsd) + # FreeBSD version: + # CC requires: -mt -lpthread for multithreaded applications + # + BINDIR = ../../../bin/freebsd +endif + +ifeq (${OS},aix) + # AIX version + BINDIR = ../../../bin/aix +endif + +ifeq (${OS},hp-ux) + # HP-UX version + BINDIR = ../../../bin/hp-ux +endif + +ifeq (${OS},irix) + # IRIX version + BINDIR = ../../../bin/irix +endif + + +# just change these around to suit your compiler and OS: +CC = gcc +CFLAGS = -c -ansi -Wall +AR = ar +ARFLAGS = rvs + +# the C source, header, and object files used by the main library: +SDP_SOURCE_FILES = SDP_Parser.c \ + SDP_EventStreamParser.c \ + SDP_StreamTokenizer.c \ + SDP_Description.c \ + SDP_Generator.c \ + SDP_Error.c \ + SDP_Str.c \ + SDP_Utility.c +SDP_HEADER_FIELS = SDP_Parser.h \ + SDP_EventStreamParser.h \ + SDP_StreamTokenizer.h \ + SDP_Description.h \ + SDP_Generator.h \ + SDP_LinkedList.h \ + SDP_Error.h \ + SDP_Str.h \ + SDP_Utility.h +SDP_OBJECT_FILES = SDP_Parser.o \ + SDP_EventStreamParser.o \ + SDP_StreamTokenizer.o \ + SDP_Description.o \ + SDP_Parser.o \ + SDP_Generator.o \ + SDP_Error.o \ + SDP_Str.o \ + SDP_Utility.o + +# the source, header, and object files used just by the generator (to build it +# separately): +SDP_GENERATOR_SOURCE_FILES = SDP_Generator.c \ + SDP_Description.c \ + SDP_Error.c \ + SDP_Str.c \ + SDP_Utility.c +SDP_GENERATOR_HEADER_FILES = SDP_Generator.h \ + SDP_Description.h \ + SDP_Error.h \ + SDP_LinkedList.h \ + SDP_Str.h \ + SDP_Utility.h +SDP_GENERATOR_OBJECT_FILES = SDP_Generator.o \ + SDP_Description.o \ + SDP_Error.o \ + SDP_Str.o \ + SDP_Utility.o + + + + + +all: libsinistersdp.a + +libsinistersdp.a: $(SDP_SOURCE_FILES) $(SDP_HEADER_FILES) + $(CC) $(CFLAGS) $(SDP_SOURCE_FILES) + $(AR) $(ARFLAGS) $@ $(SDP_OBJECT_FILES) + mv *.a "$(BINDIR)" + +# this can be used to build just the generator by itself: +libsdpgenerator.a: $(SDP_GENERATOR_SOURCE_FILES) $(SDP_GENERATOR_HEADER_FILES) + $(CC) $(CFLAGS) $(SDP_GENERATOR_SOURCE_FILES) + $(AR) $(ARFLAGS) $@ $(SDP_GENERATOR_OBJECT_FILES) + mv *.a "$(BINDIR)" + +clean: + @for f in core ${SDP_OBJECT_FILES} ; do \ + if [ -f "$${f}" ] ; then \ + rm "$${f}"; \ + fi \ + done + +cleanall : clean + @for f in ${BINDIR}/libsinistersdp.a ${BINDIR}/libsdpgenerator.a; do \ + if [ -f "$${f}" ] ; then \ + rm $${f} ; \ + fi \ + done diff --git a/src/sdp_lib/src/SDP_Description.c b/src/sdp_lib/src/SDP_Description.c new file mode 100644 index 0000000..a8eef8f --- /dev/null +++ b/src/sdp_lib/src/SDP_Description.c @@ -0,0 +1,2087 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + *------------------------------------------------------------------------------ + * + * This file contains routines to manipulate the tree of structures defined + * the SDP_Description.h file. See SinisterSdpDescriptions.html for + * documentation. + * + ******************************************************************************/ + +#include +#include "SDP_Description.h" +#include "SDP_Error.h" +#include "SDP_Str.h" +#include "SDP_LinkedList.h" +#include "SDP_Utility.h" + +/* + * We use this as a way to call SDP_CopyToStr() and ignore (well, not really) + * its possibly error-indicating return value: + */ +#define ENSURE_COPY_TO_STR(_str_, _string_to_copy_) \ + do { \ + if (SDP_FAILED(SDP_CopyToStr(&_str_, _string_to_copy_))) \ + { \ + SDP_RaiseFatalError( \ + SDP_ERR_OUT_OF_MEMORY, \ + "Couldn't allocate memory to copy string: " \ + "%s.", \ + SDP_OS_ERROR_STRING \ + ); \ + return SDP_FAILURE; \ + } \ + } while (0) + + + + + + + +/****************************************************************************** + * + * These functions create new structures for SDP fields: + * + *****************************************************************************/ + +SDP_Description *SDP_NewDescription(void) +{ + SDP_Description *description; + + description = (SDP_Description *) SDP_Allocate(sizeof(SDP_Description)); + if (description == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for session description: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(description, 0, sizeof(SDP_Description)); + + return description; +} + + + + + +SDP_Owner *SDP_NewOwner(void) +{ + SDP_Owner *owner; + + owner = (SDP_Owner *) SDP_Allocate(sizeof(SDP_Owner)); + if (owner == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for session owner " + "information: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(owner, 0, sizeof(SDP_Owner)); + + return owner; +} + + + + + +SDP_EmailContact *SDP_NewEmailContact(void) +{ + SDP_EmailContact *email_contact; + + email_contact = (SDP_EmailContact *) SDP_Allocate( + sizeof(SDP_EmailContact) + ); + if (email_contact == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for email address: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(email_contact, 0, sizeof(SDP_EmailContact)); + + return email_contact; +} + + + + + +SDP_PhoneContact *SDP_NewPhoneContact(void) +{ + SDP_PhoneContact *phone_contact; + + phone_contact = (SDP_PhoneContact *) SDP_Allocate( + sizeof(SDP_PhoneContact) + ); + if (phone_contact == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for phone number: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(phone_contact, 0, sizeof(SDP_PhoneContact)); + + return phone_contact; +} + + + + + +SDP_Connection *SDP_NewConnection(void) +{ + SDP_Connection *connection; + + connection = (SDP_Connection *) SDP_Allocate(sizeof(SDP_Connection)); + if (connection == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for connection " + "information: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(connection, 0, sizeof(SDP_Connection)); + + return connection; +} + + + + + +SDP_Bandwidth *SDP_NewBandwidth(void) +{ + SDP_Bandwidth *bandwidth; + + bandwidth = (SDP_Bandwidth *) SDP_Allocate(sizeof(SDP_Bandwidth)); + if (bandwidth == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for bandwidth " + "information: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(bandwidth, 0, sizeof(SDP_Bandwidth)); + + return bandwidth; +} + + + + + +SDP_SessionPlayTime *SDP_NewSessionPlayTime(void) +{ + SDP_SessionPlayTime *session_play_time; + + session_play_time = (SDP_SessionPlayTime *) SDP_Allocate( + sizeof(SDP_SessionPlayTime) + ); + if (session_play_time == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for session start/stop time " + "information: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(session_play_time, 0, sizeof(SDP_SessionPlayTime)); + + return session_play_time; +} + + + + + +SDP_RepeatTime *SDP_NewRepeatTime(void) +{ + SDP_RepeatTime *repeat_time; + + repeat_time = (SDP_RepeatTime *) SDP_Allocate(sizeof(SDP_RepeatTime)); + if (repeat_time == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for new repeat time " + "information: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(repeat_time, 0, sizeof(SDP_RepeatTime)); + + return repeat_time; +} + + + + + +SDP_ZoneAdjustment *SDP_NewZoneAdjustment(void) +{ + SDP_ZoneAdjustment *zone_adjustment; + + zone_adjustment = (SDP_ZoneAdjustment *) SDP_Allocate( + sizeof(SDP_ZoneAdjustment) + ); + if (zone_adjustment == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for time zone adjustment " + "information: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(zone_adjustment, 0, sizeof(SDP_ZoneAdjustment)); + + return zone_adjustment; +} + + + + + +SDP_Encryption *SDP_NewEncryption(void) +{ + SDP_Encryption *encryption; + + encryption = (SDP_Encryption *) SDP_Allocate(sizeof(SDP_Encryption)); + if (encryption == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for encryption " + "information: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(encryption, 0, sizeof(SDP_Encryption)); + + return encryption; +} + + + + + +SDP_Attribute *SDP_NewAttribute(void) +{ + SDP_Attribute *attribute; + + attribute = (SDP_Attribute *) SDP_Allocate(sizeof(SDP_Attribute)); + if (attribute == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for SDP attribute: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(attribute, 0, sizeof(SDP_Attribute)); + + return attribute; +} + + + + + +SDP_MediaDescription *SDP_NewMediaDescription(void) +{ + SDP_MediaDescription *media_description; + + media_description = (SDP_MediaDescription *) SDP_Allocate( + sizeof(SDP_MediaDescription) + ); + if (media_description == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for media description: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(media_description, 0, sizeof(SDP_MediaDescription)); + + return media_description; +} + + + + + + + +/****************************************************************************** + * + * These functions set values within members of SDP field structures: + * + *****************************************************************************/ + +void SDP_SetProtocolVersion( + SDP_Description * description, + int version) +{ + SDP_AssertNotNull(description); + + description->protocol_version = version; +} + + + + + +int SDP_SetOwner( + SDP_Description * description, + const char * username, + const char * session_id, + const char * session_version, + const char * network_type, + const char * address_type, + const char * address) +{ + SDP_AssertNotNull(description); + + if (description->owner == NULL) + { + description->owner = SDP_NewOwner(); + if (description->owner == NULL) + return SDP_FAILURE; + } + + ENSURE_COPY_TO_STR(description->owner->username, username); + ENSURE_COPY_TO_STR(description->owner->session_id, session_id); + ENSURE_COPY_TO_STR( + description->owner->session_version, session_version + ); + ENSURE_COPY_TO_STR(description->owner->network_type, network_type); + ENSURE_COPY_TO_STR(description->owner->address_type, address_type); + ENSURE_COPY_TO_STR(description->owner->address, address); + + return SDP_SUCCESS; +} + +int SDP_SetUsername( + SDP_Owner * owner, + const char * username) +{ + SDP_AssertNotNull(owner); + + ENSURE_COPY_TO_STR(owner->username, username); + + return SDP_SUCCESS; +} + +int SDP_SetSessionID( + SDP_Owner * owner, + const char * session_id) +{ + SDP_AssertNotNull(owner); + + ENSURE_COPY_TO_STR(owner->session_id, session_id); + + return SDP_SUCCESS; +} + +int SDP_SetSessionVersion( + SDP_Owner * owner, + const char * session_version) +{ + SDP_AssertNotNull(owner); + + ENSURE_COPY_TO_STR(owner->session_version, session_version); + + return SDP_SUCCESS; +} + +int SDP_SetOwnerNetworkType( + SDP_Owner * owner, + const char * network_type) +{ + SDP_AssertNotNull(owner); + + ENSURE_COPY_TO_STR(owner->network_type, network_type); + + return SDP_SUCCESS; +} + +int SDP_SetOwnerAddressType( + SDP_Owner * owner, + const char * address_type) +{ + SDP_AssertNotNull(owner); + + ENSURE_COPY_TO_STR(owner->address_type, address_type); + + return SDP_SUCCESS; +} + +int SDP_SetOwnerAddress( + SDP_Owner * owner, + const char * address) +{ + SDP_AssertNotNull(owner); + + ENSURE_COPY_TO_STR(owner->address, address); + + return SDP_SUCCESS; +} + + + + + +int SDP_SetSessionName( + SDP_Description * description, + const char * session_name) +{ + SDP_AssertNotNull(description); + + ENSURE_COPY_TO_STR(description->session_name, session_name); + + return SDP_SUCCESS; +} + + + + + +int SDP_SetSessionInformation( + SDP_Description * description, + const char * session_information) +{ + SDP_AssertNotNull(description); + + ENSURE_COPY_TO_STR( + description->session_information, session_information + ); + + return SDP_SUCCESS; +} + + + + + +int SDP_SetURI( + SDP_Description * description, + const char * uri) +{ + SDP_AssertNotNull(description); + + ENSURE_COPY_TO_STR(description->uri, uri); + + return SDP_SUCCESS; +} + + + + + +void SDP_AddEmailContact( + SDP_Description * description, + SDP_EmailContact * email_contact) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(email_contact); + + SDP_LINK_INTO_LIST( + description->email_contacts, + email_contact, + SDP_EmailContact + ); +} + +int SDP_AddNewEmailContact( + SDP_Description * description, + const char * address, + const char * name) +{ + SDP_EmailContact *email_contact; + + SDP_AssertNotNull(description); + + email_contact = SDP_NewEmailContact(); + if (email_contact == NULL) + return SDP_FAILURE; + + ENSURE_COPY_TO_STR(email_contact->address, address); + ENSURE_COPY_TO_STR(email_contact->name, name); + + SDP_AddEmailContact(description, email_contact); + + return SDP_SUCCESS; +} + +int SDP_SetEmailAddress( + SDP_EmailContact * email_contact, + const char * address) +{ + SDP_AssertNotNull(email_contact); + + ENSURE_COPY_TO_STR(email_contact->address, address); + + return SDP_SUCCESS; +} + +int SDP_SetEmailName( + SDP_EmailContact * email_contact, + const char * name) +{ + SDP_AssertNotNull(email_contact); + + ENSURE_COPY_TO_STR(email_contact->name, name); + + return SDP_SUCCESS; +} + + + + + +void SDP_AddPhoneContact( + SDP_Description * description, + SDP_PhoneContact * phone_contact) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(phone_contact); + + SDP_LINK_INTO_LIST( + description->phone_contacts, + phone_contact, + SDP_PhoneContact + ); +} + +int SDP_AddNewPhoneContact( + SDP_Description * description, + const char * number, + const char * name) +{ + SDP_PhoneContact *phone_contact; + + SDP_AssertNotNull(description); + + phone_contact = + (SDP_PhoneContact *) SDP_Allocate(sizeof(SDP_PhoneContact)); + if (phone_contact == NULL) + return SDP_FAILURE; + + ENSURE_COPY_TO_STR(phone_contact->number, number); + ENSURE_COPY_TO_STR(phone_contact->name, name); + + SDP_AddPhoneContact(description, phone_contact); + + return SDP_SUCCESS; +} + +int SDP_SetPhoneNumber( + SDP_PhoneContact * phone_contact, + const char * number) +{ + SDP_AssertNotNull(phone_contact); + + ENSURE_COPY_TO_STR(phone_contact->number, number); + + return SDP_SUCCESS; +} + +int SDP_SetPhoneName( + SDP_PhoneContact * phone_contact, + const char * name) +{ + SDP_AssertNotNull(phone_contact); + + ENSURE_COPY_TO_STR(phone_contact->name, name); + + return SDP_SUCCESS; +} + + + + + +int SDP_SetConnection( + SDP_Description * description, + const char * network_type, + const char * address_type, + const char * address, + int ttl, + int total_addresses) +{ + SDP_AssertNotNull(description); + + if (description->connection == NULL) + { + description->connection = SDP_NewConnection(); + if (description->connection == NULL) + return SDP_FAILURE; + } + + ENSURE_COPY_TO_STR( + description->connection->network_type, network_type + ); + ENSURE_COPY_TO_STR( + description->connection->address_type, address_type + ); + ENSURE_COPY_TO_STR( + description->connection->address, address + ); + description->connection->ttl = ttl; + description->connection->total_addresses = total_addresses; + + return SDP_SUCCESS; +} + +int SDP_SetConnectionNetworkType( + SDP_Connection * connection, + const char * network_type) +{ + SDP_AssertNotNull(connection); + + ENSURE_COPY_TO_STR(connection->network_type, network_type); + + return SDP_SUCCESS; +} + +int SDP_SetConnectionAddressType( + SDP_Connection * connection, + const char * address_type) +{ + SDP_AssertNotNull(connection); + + ENSURE_COPY_TO_STR(connection->address_type, address_type); + + return SDP_SUCCESS; +} + +int SDP_SetConnectionAddress( + SDP_Connection * connection, + const char * address) +{ + SDP_AssertNotNull(connection); + + ENSURE_COPY_TO_STR(connection->address, address); + + return SDP_SUCCESS; +} + +void SDP_SetConnectionTTL( + SDP_Connection * connection, + int ttl) +{ + SDP_AssertNotNull(connection); + + connection->ttl = ttl; +} + +void SDP_SetTotalConnectionAddresses( + SDP_Connection * connection, + int total_addresses) +{ + SDP_AssertNotNull(connection); + + connection->total_addresses = total_addresses; +} + + + + + +int SDP_SetBandwidth( + SDP_Description * description, + const char * modifier, + long value) +{ + SDP_AssertNotNull(description); + + if (description->bandwidth == NULL) + { + description->bandwidth = SDP_NewBandwidth(); + if (description->bandwidth == NULL) + return SDP_FAILURE; + } + + ENSURE_COPY_TO_STR(description->bandwidth->modifier, modifier); + description->bandwidth->value = value; + + return SDP_SUCCESS; +} + +int SDP_SetBandwidthModifier( + SDP_Bandwidth * bandwidth, + const char * modifier) +{ + SDP_AssertNotNull(bandwidth); + + ENSURE_COPY_TO_STR(bandwidth->modifier, modifier); + + return SDP_SUCCESS; +} + +void SDP_SetBandwidthValue( + SDP_Bandwidth * bandwidth, + long value) +{ + SDP_AssertNotNull(bandwidth); + + bandwidth->value = value; +} + + + + + +void SDP_AddSessionPlayTime( + SDP_Description * description, + SDP_SessionPlayTime * session_play_time) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(session_play_time); + + SDP_LINK_INTO_LIST( + description->session_play_times, + session_play_time, + SDP_SessionPlayTime + ); +} + +int SDP_AddNewSessionPlayTime( + SDP_Description * description, + time_t start_time, + time_t end_time) +{ + SDP_SessionPlayTime *session_play_time; + + SDP_AssertNotNull(description); + + session_play_time = SDP_NewSessionPlayTime(); + if (session_play_time == NULL) + return SDP_FAILURE; + + session_play_time->start_time = start_time; + session_play_time->end_time = end_time; + + SDP_AddSessionPlayTime(description, session_play_time); + + return SDP_SUCCESS; +} + +void SDP_SetStartTime( + SDP_SessionPlayTime * session_play_time, + time_t start_time) +{ + SDP_AssertNotNull(session_play_time); + + session_play_time->start_time = start_time; +} + +void SDP_SetEndTime( + SDP_SessionPlayTime * session_play_time, + time_t end_time) +{ + SDP_AssertNotNull(session_play_time); + + session_play_time->end_time = end_time; +} + +void SDP_AddRepeatTime( + SDP_SessionPlayTime * session_play_time, + SDP_RepeatTime * repeat_time) +{ + SDP_AssertNotNull(session_play_time); + SDP_AssertNotNull(repeat_time); + + SDP_LINK_INTO_LIST( + session_play_time->repeat_times, + repeat_time, + SDP_RepeatTime + ); +} + +int SDP_AddNewRepeatTime( + SDP_SessionPlayTime * session_play_time, + unsigned long repeat_interval, + unsigned long active_duration, + const unsigned long repeat_offsets[], + int total_offsets) +{ + SDP_RepeatTime *repeat_time; + + SDP_AssertNotNull(session_play_time); + + repeat_time = SDP_NewRepeatTime(); + if (repeat_time == NULL) + return SDP_FAILURE; + + repeat_time->repeat_interval = repeat_interval; + repeat_time->active_duration = active_duration; + + if (total_offsets) + { + int rc = SDP_SetRepeatOffsets( + repeat_time, repeat_offsets, total_offsets + ); + if (SDP_FAILED(rc)) + return SDP_FAILURE; + } + + SDP_AddRepeatTime(session_play_time, repeat_time); + + return SDP_SUCCESS; +} + +void SDP_SetRepeatInterval( + SDP_RepeatTime * repeat_time, + unsigned long repeat_interval) +{ + SDP_AssertNotNull(repeat_time); + + repeat_time->repeat_interval = repeat_interval; +} + +void SDP_SetActiveDuration( + SDP_RepeatTime * repeat_time, + unsigned long active_duration) +{ + SDP_AssertNotNull(repeat_time); + + repeat_time->active_duration = active_duration; +} + +int SDP_SetRepeatOffsets( + SDP_RepeatTime * repeat_time, + const unsigned long repeat_offsets[], + int total_offsets) +{ + SDP_AssertNotNull(repeat_time); + + if (total_offsets) + { + int i; + + repeat_time->repeat_offsets = (unsigned long *) SDP_Allocate( + sizeof(unsigned long) * total_offsets + ); + if (repeat_time->repeat_offsets == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy repeat " + "offsets: %s.", + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + for (i = 0; i < total_offsets; ++i) + repeat_time->repeat_offsets[i] = repeat_offsets[i]; + + repeat_time->total_offsets = total_offsets; + } + + return SDP_SUCCESS; +} + + + + + +void SDP_AddZoneAdjustment( + SDP_Description * description, + SDP_ZoneAdjustment * zone_adjustment) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(zone_adjustment); + + SDP_LINK_INTO_LIST( + description->zone_adjustments, + zone_adjustment, + SDP_ZoneAdjustment + ); +} + +int SDP_AddNewZoneAdjustment( + SDP_Description * description, + time_t time, + long offset) +{ + SDP_ZoneAdjustment *zone_adjustment; + + SDP_AssertNotNull(description); + + zone_adjustment = SDP_NewZoneAdjustment(); + if (zone_adjustment == NULL) + return SDP_FAILURE; + + zone_adjustment->time = time; + zone_adjustment->offset = offset; + + SDP_AddZoneAdjustment(description, zone_adjustment); + + return SDP_SUCCESS; +} + +void SDP_SetZoneAdjustmentTime( + SDP_ZoneAdjustment * zone_adjustment, + time_t time) +{ + SDP_AssertNotNull(zone_adjustment); + + zone_adjustment->time = time; +} + +void SDP_SetZoneAdjustmentOffset( + SDP_ZoneAdjustment * zone_adjustment, + long offset) +{ + SDP_AssertNotNull(zone_adjustment); + + zone_adjustment->offset = offset; +} + + + + + +int SDP_SetEncryption( + SDP_Description * description, + const char * method, + const char * key) +{ + SDP_AssertNotNull(description); + + if (description->encryption == NULL) + { + description->encryption = SDP_NewEncryption(); + if (description->encryption == NULL) + return SDP_FAILURE; + } + + ENSURE_COPY_TO_STR(description->encryption->method, method); + ENSURE_COPY_TO_STR(description->encryption->key, key); + + return SDP_SUCCESS; +} + +int SDP_SetEncryptionMethod( + SDP_Encryption * encryption, + const char * method) +{ + SDP_AssertNotNull(encryption); + + ENSURE_COPY_TO_STR(encryption->method, method); + + return SDP_SUCCESS; +} + +int SDP_SetEncryptionKey( + SDP_Encryption * encryption, + const char * key) +{ + SDP_AssertNotNull(encryption); + + ENSURE_COPY_TO_STR(encryption->key, key); + + return SDP_SUCCESS; +} + + + + + +void SDP_AddAttribute( + SDP_Description * description, + SDP_Attribute * attribute) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(attribute); + + SDP_LINK_INTO_LIST( + description->attributes, + attribute, + SDP_Attribute + ); +} + +int SDP_AddNewAttribute( + SDP_Description * description, + const char * name, + const char * value) +{ + SDP_Attribute *attribute; + + SDP_AssertNotNull(description); + + attribute = SDP_NewAttribute(); + if (attribute == NULL) + return SDP_FAILURE; + + ENSURE_COPY_TO_STR(attribute->name, name); + ENSURE_COPY_TO_STR(attribute->value, value); + + SDP_AddAttribute(description, attribute); + + return SDP_SUCCESS; +} + +int SDP_SetAttributeName( + SDP_Attribute * attribute, + const char * name) +{ + SDP_AssertNotNull(attribute); + + ENSURE_COPY_TO_STR(attribute->name, name); + + return SDP_SUCCESS; +} + +int SDP_SetAttributeValue( + SDP_Attribute * attribute, + const char * value) +{ + SDP_AssertNotNull(attribute); + + ENSURE_COPY_TO_STR(attribute->value, value); + + return SDP_SUCCESS; +} + + + + + +void SDP_AddMediaDescription( + SDP_Description * description, + SDP_MediaDescription * media_description) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(media_description); + + SDP_LINK_INTO_LIST( + description->media_descriptions, + media_description, + SDP_MediaDescription + ); +} + +int SDP_AddNewMediaDescription( + SDP_Description * description, + const char * media_type, + unsigned short port, + unsigned short total_ports, + const char * transport_protocol, + const char * formats, + const char * media_information) +{ + SDP_MediaDescription *media_description; + + SDP_AssertNotNull(description); + + media_description = SDP_NewMediaDescription(); + if (media_description == NULL) + return SDP_FAILURE; + + SDP_AddMediaDescription(description, media_description); + + ENSURE_COPY_TO_STR(media_description->media_type, media_type); + media_description->port = port; + media_description->total_ports = total_ports; + ENSURE_COPY_TO_STR( + media_description->transport_protocol, + transport_protocol + ); + ENSURE_COPY_TO_STR(media_description->formats, formats); + ENSURE_COPY_TO_STR( + media_description->media_information, + media_information + ); + + return SDP_SUCCESS; +} + +int SDP_SetMediaType( + SDP_MediaDescription * media_description, + const char * media_type) +{ + SDP_AssertNotNull(media_description); + + ENSURE_COPY_TO_STR(media_description->media_type, media_type); + + return SDP_SUCCESS; +} + +void SDP_SetMediaPort( + SDP_MediaDescription * media_description, + unsigned short port) +{ + SDP_AssertNotNull(media_description); + + media_description->port = port; +} + +void SDP_SetTotalMediaPorts( + SDP_MediaDescription * media_description, + unsigned short total_ports) +{ + SDP_AssertNotNull(media_description); + + media_description->total_ports = total_ports; +} + +int SDP_SetMediaTransportProtocol( + SDP_MediaDescription * media_description, + const char * transport_protocol) +{ + SDP_AssertNotNull(media_description); + + ENSURE_COPY_TO_STR( + media_description->transport_protocol, + transport_protocol + ); + + return SDP_SUCCESS; +} + +int SDP_SetMediaFormats( + SDP_MediaDescription * media_description, + const char * formats) +{ + SDP_AssertNotNull(media_description); + + ENSURE_COPY_TO_STR(media_description->formats, formats); + + return SDP_SUCCESS; +} + +int SDP_SetMediaInformation( + SDP_MediaDescription * media_description, + const char * media_information) +{ + SDP_AssertNotNull(media_description); + + ENSURE_COPY_TO_STR( + media_description->media_information, + media_information + ); + + return SDP_SUCCESS; +} + +int SDP_SetMediaConnection( + SDP_MediaDescription * media_description, + const char * network_type, + const char * address_type, + const char * address, + int ttl, + int total_addresses) +{ + SDP_AssertNotNull(media_description); + + if (media_description->connection == NULL) + { + media_description->connection = SDP_NewConnection(); + if (media_description->connection == NULL) + return SDP_FAILURE; + } + + ENSURE_COPY_TO_STR( + media_description->connection->network_type, + network_type + ); + ENSURE_COPY_TO_STR( + media_description->connection->address_type, + address_type + ); + ENSURE_COPY_TO_STR( + media_description->connection->address, + address + ); + media_description->connection->ttl = ttl; + media_description->connection->total_addresses = total_addresses; + + return SDP_SUCCESS; +} + +int SDP_SetMediaBandwidth( + SDP_MediaDescription * media_description, + const char * modifier, + long value) +{ + SDP_AssertNotNull(media_description); + + if (media_description->bandwidth == NULL) + { + media_description->bandwidth = SDP_NewBandwidth(); + if (media_description->bandwidth == NULL) + return SDP_FAILURE; + } + + ENSURE_COPY_TO_STR(media_description->bandwidth->modifier, modifier); + media_description->bandwidth->value = value; + + return SDP_SUCCESS; +} + +int SDP_SetMediaEncryption( + SDP_MediaDescription * media_description, + const char * method, + const char * key) +{ + SDP_AssertNotNull(media_description); + + if (media_description->encryption == NULL) + { + media_description->encryption = SDP_NewEncryption(); + if (media_description->encryption == NULL) + return SDP_FAILURE; + } + + ENSURE_COPY_TO_STR(media_description->encryption->method, method); + ENSURE_COPY_TO_STR(media_description->encryption->key, key); + + return SDP_SUCCESS; +} + +void SDP_AddMediaAttribute( + SDP_MediaDescription * media_description, + SDP_Attribute * attribute) +{ + SDP_AssertNotNull(media_description); + SDP_AssertNotNull(attribute); + + SDP_LINK_INTO_LIST( + media_description->attributes, + attribute, + SDP_Attribute + ); +} + +int SDP_AddNewMediaAttribute( + SDP_MediaDescription * media_description, + const char * name, + const char * value) +{ + SDP_Attribute *attribute; + + SDP_AssertNotNull(media_description); + + attribute = SDP_NewAttribute(); + if (attribute == NULL) + return SDP_FAILURE; + + ENSURE_COPY_TO_STR(attribute->name, name); + ENSURE_COPY_TO_STR(attribute->value, value); + + SDP_AddMediaAttribute(media_description, attribute); + + return SDP_SUCCESS; +} + + + + + + + +/****************************************************************************** + * + * These functions retrieve values from members within SDP field structures: + * + *****************************************************************************/ + +int SDP_GetProtocolVersion(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return description->protocol_version; +} + + + + + +SDP_Owner *SDP_GetOwner(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return description->owner; +} + +const char *SDP_GetUsername(SDP_Owner *owner) +{ + return owner ? SDP_GetStrBuffer(owner->username) : NULL; +} + +const char *SDP_GetSessionID(SDP_Owner *owner) +{ + return owner ? SDP_GetStrBuffer(owner->session_id) : NULL; +} + +const char *SDP_GetSessionVersion(SDP_Owner *owner) +{ + return owner ? SDP_GetStrBuffer(owner->session_version) : NULL; +} + +const char *SDP_GetOwnerNetworkType(SDP_Owner *owner) +{ + return owner ? SDP_GetStrBuffer(owner->network_type) : NULL; +} + +const char *SDP_GetOwnerAddressType(SDP_Owner *owner) +{ + return owner ? SDP_GetStrBuffer(owner->address_type) : NULL; +} + +const char *SDP_GetOwnerAddress(SDP_Owner *owner) +{ + return owner ? SDP_GetStrBuffer(owner->address) : NULL; +} + + + + + +const char *SDP_GetSessionName(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return SDP_GetStrBuffer(description->session_name); +} + + + + + +const char *SDP_GetSessionInformation(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return SDP_GetStrBuffer(description->session_information); +} + + + + + +const char *SDP_GetURI(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return SDP_GetStrBuffer(description->uri); +} + + + + + +SDP_EmailContact *SDP_GetEmailContacts(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return SDP_GetListElements(description->email_contacts); +} + +const char *SDP_GetEmailAddress(SDP_EmailContact *email_contact) +{ + return email_contact ? SDP_GetStrBuffer(email_contact->address) : NULL; +} + +const char *SDP_GetEmailName(SDP_EmailContact *email_contact) +{ + return email_contact ? SDP_GetStrBuffer(email_contact->name) : NULL; +} + +void SDP_RemoveEmailContact( + SDP_Description * description, + SDP_EmailContact * email_contact) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(email_contact); + + SDP_UNLINK_FROM_LIST( + description->email_contacts, + email_contact, + SDP_EmailContact + ); +} + + + + + +SDP_PhoneContact *SDP_GetPhoneContacts(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return SDP_GetListElements(description->phone_contacts); +} + +const char *SDP_GetPhoneNumber(SDP_PhoneContact *phone_contact) +{ + return phone_contact ? SDP_GetStrBuffer(phone_contact->number) : NULL; +} + +const char *SDP_GetPhoneName(SDP_PhoneContact *phone_contact) +{ + return phone_contact ? SDP_GetStrBuffer(phone_contact->name) : NULL; +} + +void SDP_RemovePhoneContact( + SDP_Description * description, + SDP_PhoneContact * phone_contact) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(phone_contact); + + SDP_UNLINK_FROM_LIST( + description->phone_contacts, + phone_contact, + SDP_PhoneContact + ); +} + + + + + +SDP_Connection *SDP_GetConnection(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return description->connection; +} + +const char *SDP_GetConnectionNetworkType(SDP_Connection *connection) +{ + return connection ? SDP_GetStrBuffer(connection->network_type) : NULL; +} + +const char *SDP_GetConnectionAddressType(SDP_Connection *connection) +{ + return connection ? SDP_GetStrBuffer(connection->address_type) : NULL; +} + +const char *SDP_GetConnectionAddress(SDP_Connection *connection) +{ + return connection ? SDP_GetStrBuffer(connection->address) : NULL; +} + +int SDP_GetConnectionTTL(SDP_Connection *connection) +{ + return connection ? connection->ttl : 0; +} + +int SDP_GetTotalConnectionAddresses(SDP_Connection *connection) +{ + return connection ? connection->total_addresses : 0; +} + + + + + +SDP_Bandwidth *SDP_GetBandwidth(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return description->bandwidth; +} + +const char *SDP_GetBandwidthModifier(SDP_Bandwidth *bandwidth) +{ + return bandwidth ? SDP_GetStrBuffer(bandwidth->modifier) : NULL; +} + +long SDP_GetBandwidthValue(SDP_Bandwidth *bandwidth) +{ + return bandwidth ? bandwidth->value : 0L; +} + + + + + +SDP_SessionPlayTime *SDP_GetSessionPlayTimes(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return SDP_GetListElements(description->session_play_times); +} + +time_t SDP_GetStartTime(SDP_SessionPlayTime *session_play_time) +{ + return session_play_time ? session_play_time->start_time : 0; +} + +time_t SDP_GetEndTime(SDP_SessionPlayTime *session_play_time) +{ + return session_play_time ? session_play_time->end_time : 0; +} + +SDP_RepeatTime *SDP_GetRepeatTimes(SDP_SessionPlayTime *session_play_time) +{ + return SDP_GetListElements(session_play_time->repeat_times); +} + +unsigned long SDP_GetRepeatInterval(SDP_RepeatTime *repeat_times) +{ + return repeat_times ? repeat_times->repeat_interval : 0; +} + +unsigned long SDP_GetActiveDuration(SDP_RepeatTime *repeat_times) +{ + return repeat_times ? repeat_times->active_duration : 0; +} + +unsigned long *SDP_GetRepeatOffsets(SDP_RepeatTime *repeat_times) +{ + return repeat_times ? repeat_times->repeat_offsets : NULL; +} + +int SDP_GetTotalRepeatOffsets(SDP_RepeatTime *repeat_times) +{ + return repeat_times ? repeat_times->total_offsets : 0; +} + +void SDP_RemoveRepeatTime( + SDP_SessionPlayTime * session_play_times, + SDP_RepeatTime * repeat_time) +{ + SDP_AssertNotNull(session_play_times); + SDP_AssertNotNull(repeat_time); + + SDP_UNLINK_FROM_LIST( + session_play_times->repeat_times, + repeat_time, + SDP_SessionPlayTime + ); +} + +void SDP_RemoveSessionPlayTime( + SDP_Description * description, + SDP_SessionPlayTime * session_play_time) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(session_play_time); + + SDP_UNLINK_FROM_LIST( + description->session_play_times, + session_play_time, + SDP_SessionPlayTime + ); +} + + + + + +SDP_ZoneAdjustment *SDP_GetZoneAdjustments(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return SDP_GetListElements(description->zone_adjustments); +} + +time_t SDP_GetZoneAdjustmentTime(SDP_ZoneAdjustment *zone_adjustment) +{ + return zone_adjustment ? zone_adjustment->time : 0; +} + +long SDP_GetZoneAdjustmentOffset(SDP_ZoneAdjustment *zone_adjustment) +{ + return zone_adjustment ? zone_adjustment->offset : 0; +} + +void SDP_RemoveZoneAdjustment( + SDP_Description * description, + SDP_ZoneAdjustment * zone_adjustment) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(zone_adjustment); + + SDP_UNLINK_FROM_LIST( + description->zone_adjustments, + zone_adjustment, + SDP_ZoneAdjustment + ); +} + + + + + +SDP_Encryption *SDP_GetEncryption(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return description->encryption; +} + +const char *SDP_GetEncryptionMethod(SDP_Encryption *encryption) +{ + return encryption ? SDP_GetStrBuffer(encryption->method) : NULL; +} + +const char *SDP_GetEncryptionKey(SDP_Encryption *encryption) +{ + return encryption ? SDP_GetStrBuffer(encryption->key) : NULL; +} + + + + + +SDP_Attribute *SDP_GetAttributes(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return SDP_GetListElements(description->attributes); +} + +const char *SDP_GetAttributeName(SDP_Attribute *attribute) +{ + return attribute ? SDP_GetStrBuffer(attribute->name) : NULL; +} + +const char *SDP_GetAttributeValue(SDP_Attribute *attribute) +{ + return attribute ? SDP_GetStrBuffer(attribute->value) : NULL; +} + +void SDP_RemoveAttribute( + SDP_Description * description, + SDP_Attribute * attribute) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(attribute); + + SDP_UNLINK_FROM_LIST( + description->attributes, + attribute, + SDP_Attribute + ); +} + + + + + +SDP_MediaDescription *SDP_GetMediaDescriptions(SDP_Description *description) +{ + SDP_AssertNotNull(description); + + return SDP_GetListElements(description->media_descriptions); +} + +const char *SDP_GetMediaType(SDP_MediaDescription *media_description) +{ + return media_description + ? SDP_GetStrBuffer(media_description->media_type) + : NULL; +} + +unsigned short SDP_GetMediaPort(SDP_MediaDescription *media_description) +{ + return media_description ? media_description->port : 0; +} + +unsigned short SDP_GetTotalMediaPorts(SDP_MediaDescription *media_description) +{ + return media_description ? media_description->total_ports : 0; +} + +const char *SDP_GetMediaTransportProtocol( + SDP_MediaDescription *media_description) +{ + return media_description + ? SDP_GetStrBuffer(media_description->transport_protocol) + : NULL; +} + +const char *SDP_GetMediaFormats(SDP_MediaDescription *media_description) +{ + return media_description + ? SDP_GetStrBuffer(media_description->formats) + : NULL; +} + +const char *SDP_GetMediaInformation(SDP_MediaDescription *media_description) +{ + return media_description + ? SDP_GetStrBuffer(media_description->media_information) + : NULL; +} + +SDP_Connection *SDP_GetMediaConnection(SDP_MediaDescription *media_description) +{ + return media_description ? media_description->connection : NULL; +} + +SDP_Bandwidth *SDP_GetMediaBandwidth(SDP_MediaDescription *media_description) +{ + return media_description ? media_description->bandwidth : NULL; +} + +SDP_Encryption *SDP_GetMediaEncryption(SDP_MediaDescription *media_description) +{ + return media_description ? media_description->encryption : NULL; +} + +SDP_Attribute *SDP_GetMediaAttributes(SDP_MediaDescription *media_description) +{ + return media_description + ? SDP_GetListElements(media_description->attributes) + : NULL; +} + +void SDP_RemoveMediaDescription( + SDP_Description * description, + SDP_MediaDescription * media_description) +{ + SDP_AssertNotNull(description); + SDP_AssertNotNull(media_description); + + SDP_UNLINK_FROM_LIST( + description->media_descriptions, + media_description, + SDP_MediaDescription + ); +} + + + + + +/******************************************************************************* + * + * These functions destroy SDP structures: + * + ******************************************************************************/ + +void SDP_DestroyDescriptions(SDP_Description *descriptions) +{ + SDP_Description *description = descriptions; + + while (description) + { + SDP_Description *description_to_destroy = description; + + description = SDP_GetNextDescription(description); + + SDP_DestroyDescription(description_to_destroy); + } +} + +void SDP_DestroyDescription(SDP_Description *description) +{ + if (description == NULL) + return; + + SDP_DestroyOwner(description->owner); + + SDP_DestroyStrBuffer(&description->session_name); + SDP_DestroyStrBuffer(&description->session_information); + SDP_DestroyStrBuffer(&description->uri); + + SDP_DestroyEmailContacts(description); + SDP_DestroyPhoneContacts(description); + SDP_DestroyConnection(description->connection); + SDP_DestroyBandwidth(description->bandwidth); + SDP_DestroySessionPlayTimes(description); + SDP_DestroyZoneAdjustments(description); + SDP_DestroyEncryption(description->encryption); + SDP_DestroyAttributes(description); + SDP_DestroyMediaDescriptions(description); + + SDP_Destroy(description); +} + + + + + +void SDP_DestroyOwner(SDP_Owner *owner) +{ + if (owner == NULL) + return; + + SDP_DestroyStrBuffer(&owner->username); + SDP_DestroyStrBuffer(&owner->session_id); + SDP_DestroyStrBuffer(&owner->network_type); + SDP_DestroyStrBuffer(&owner->address_type); + SDP_DestroyStrBuffer(&owner->address); + + SDP_Destroy(owner); +} + + + + + +void SDP_DestroyEmailContacts(SDP_Description *description) +{ + SDP_DESTROY_LIST( + description->email_contacts, + SDP_EmailContact, + SDP_DestroyEmailContact + ); +} + +void SDP_DestroyEmailContact(SDP_EmailContact *email_contact) +{ + if (email_contact == NULL) + return; + + SDP_DestroyStrBuffer(&email_contact->address); + SDP_DestroyStrBuffer(&email_contact->name); + + SDP_Destroy(email_contact); +} + + + + + +void SDP_DestroyPhoneContacts(SDP_Description *description) +{ + SDP_DESTROY_LIST( + description->phone_contacts, + SDP_PhoneContact, + SDP_DestroyPhoneContact + ); +} + +void SDP_DestroyPhoneContact(SDP_PhoneContact *phone_contact) +{ + if (phone_contact == NULL) + return; + + SDP_DestroyStrBuffer(&phone_contact->number); + SDP_DestroyStrBuffer(&phone_contact->name); + + SDP_Destroy(phone_contact); +} + + + + + +void SDP_DestroyConnection(SDP_Connection *connection) +{ + if (connection == NULL) + return; + + SDP_DestroyStrBuffer(&connection->network_type); + SDP_DestroyStrBuffer(&connection->address_type); + SDP_DestroyStrBuffer(&connection->address); + + SDP_Destroy(connection); +} + + + + + +void SDP_DestroyBandwidth(SDP_Bandwidth *bandwidth) +{ + if (bandwidth == NULL) + return; + + SDP_DestroyStrBuffer(&bandwidth->modifier); + + SDP_Destroy(bandwidth); +} + + + + + +void SDP_DestroySessionPlayTimes(SDP_Description *description) +{ + SDP_DESTROY_LIST( + description->session_play_times, + SDP_SessionPlayTime, + SDP_DestroySessionPlayTime + ); +} + +void SDP_DestroySessionPlayTime(SDP_SessionPlayTime *session_play_time) +{ + if (session_play_time == NULL) + return; + + SDP_DestroyRepeatTimes(session_play_time); + + SDP_Destroy(session_play_time); +} + +void SDP_DestroyRepeatTimes(SDP_SessionPlayTime *session_play_time) +{ + SDP_DESTROY_LIST( + session_play_time->repeat_times, + SDP_RepeatTime, + SDP_DestroyRepeatTime + ); +} + +void SDP_DestroyRepeatTime(SDP_RepeatTime *repeat_time) +{ + if (repeat_time == NULL) + return; + + if (repeat_time->repeat_offsets) + SDP_Destroy(repeat_time->repeat_offsets); + + SDP_Destroy(repeat_time); +} + + + +void SDP_DestroyZoneAdjustments(SDP_Description *description) +{ + SDP_DESTROY_LIST( + description->zone_adjustments, + SDP_ZoneAdjustment, + SDP_DestroyZoneAdjustment + ); +} + +void SDP_DestroyZoneAdjustment(SDP_ZoneAdjustment *zone_adjustment) +{ + if (zone_adjustment == NULL) + return; + + SDP_Destroy(zone_adjustment); +} + + + + + +void SDP_DestroyEncryption(SDP_Encryption *encryption) +{ + if (encryption == NULL) + return; + + SDP_DestroyStrBuffer(&encryption->method); + SDP_DestroyStrBuffer(&encryption->key); + + SDP_Destroy(encryption); +} + + + + + +void SDP_DestroyAttributes(SDP_Description *description) +{ + SDP_DESTROY_LIST( + description->attributes, + SDP_Attribute, + SDP_DestroyAttribute + ); +} + +void SDP_DestroyAttribute(SDP_Attribute *attribute) +{ + if (attribute == NULL) + return; + + SDP_DestroyStrBuffer(&attribute->name); + SDP_DestroyStrBuffer(&attribute->value); + + SDP_Destroy(attribute); +} + + + + + +void SDP_DestroyMediaDescriptions(SDP_Description *description) +{ + SDP_DESTROY_LIST( + description->media_descriptions, + SDP_MediaDescription, + SDP_DestroyMediaDescription + ); +} + +void SDP_DestroyMediaDescription(SDP_MediaDescription *media_description) +{ + if (media_description == NULL) + return; + + SDP_DestroyStrBuffer(&media_description->media_type); + SDP_DestroyStrBuffer(&media_description->transport_protocol); + SDP_DestroyStrBuffer(&media_description->formats); + SDP_DestroyStrBuffer(&media_description->media_information); + + SDP_DestroyConnection(media_description->connection); + SDP_DestroyBandwidth(media_description->bandwidth); + SDP_DestroyEncryption(media_description->encryption); + SDP_DestroyMediaAttributes(media_description); +} + + + + + +void SDP_DestroyMediaAttributes(SDP_MediaDescription *media_description) +{ + SDP_DESTROY_LIST( + media_description->attributes, + SDP_Attribute, + SDP_DestroyAttribute + ); +} diff --git a/src/sdp_lib/src/SDP_Description.h b/src/sdp_lib/src/SDP_Description.h new file mode 100755 index 0000000..066f2d4 --- /dev/null +++ b/src/sdp_lib/src/SDP_Description.h @@ -0,0 +1,827 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SDP_DESCRIPTION_INCLUDED +#define SDP_DESCRIPTION_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SDP_Str.h" +#include "SDP_LinkedList.h" + + +/* Skip down to SDP_Description before looking at these. */ + +/* The "o" field struct: */ +typedef struct { + /* + * A string containing the username of the originator of the session or + * "-" if there was none: + */ + SDP_Str username; + + /* A string containing the session ID: */ + SDP_Str session_id; + + /* + * The session version number (a string, since we don't know for sure + * how it will be represented): + */ + SDP_Str session_version; + + /* + * A string containing the network type portion of the "o" field + * (e.g., "IN" for Internet): + */ + SDP_Str network_type; + + /* A string containing the address type (e.g, "IP4"): */ + SDP_Str address_type; + + /* A string containing a dotted IP address (e.g, "127.0.0.1"): */ + SDP_Str address; +} SDP_Owner; + + + +/* The "e" field struct: */ +typedef struct _SDP_EmailContact { + /* A string containing an email address: */ + SDP_Str address; + + /* + * A string containing the name of the supposed owner of the email + * address: + */ + SDP_Str name; + + /* A pointer to the next email address in the linked list: */ + struct _SDP_EmailContact *next; + + /* A pointer to the previous email address in the linked list: */ + struct _SDP_EmailContact *previous; +} SDP_EmailContact; + + + +/* The "p" fields struct: */ +typedef struct _SDP_PhoneContact { + /* A string containing some kind of phone number: */ + SDP_Str number; + + /* + * A string containing the name of the person who can be reached at + * that phone number: + */ + SDP_Str name; + + /* A pointer to the next phone number in the linked list: */ + struct _SDP_PhoneContact *next; + + /* A pointer to the previous phone number in the linked list: */ + struct _SDP_PhoneContact *previous; +} SDP_PhoneContact; + + + +/* The struct for session-level and media-level "c" fields: */ +typedef struct { + /* + * A string containing the type of network the session or media is on: + */ + SDP_Str network_type; + + /* + * A string containing address type of the address the session or media + * is coming from: + */ + SDP_Str address_type; + + /* + * A string containing a dotted IP address (e.g., "127.0.0.1") of the + * machine the session or media is coming from: + */ + SDP_Str address; + + /* Time To Live */ + int ttl; + + /* + * Counting up from the subnet in "address", how many other address are + * available? + */ + int total_addresses; +} SDP_Connection; + + + +/* Struct for session-level and media-level "b" fields: */ +typedef struct { + /* + * A string containing a modifier (e.g., "CT" for conference total) of + * what the maximum bandwidth value applies to: + */ + SDP_Str modifier; + + /* A suggested maximum bandwidth value: */ + long value; +} SDP_Bandwidth; + + + +/* The struct for the optional "r" fields that follow a "t" field: */ +typedef struct _SDP_RepeatTime { + /* This stores the repeat interval (in seconds): */ + unsigned long repeat_interval; + + /* + * And this stores the active duration of the session (which means + * the end_time field in the session play time struct below is + * ignored): + */ + unsigned long active_duration; + + /* + * This stores a pointer to an array of numbers, where each number is + * the number of seconds for each repeat offset: + */ + unsigned long *repeat_offsets; + + /* ...and this stores the number of elements in the array: */ + int total_offsets; + + /* A pointer to next repeat time in the linked list: */ + struct _SDP_RepeatTime *next; + + /* A pointer to the previous repeat time in the linked list: */ + struct _SDP_RepeatTime *previous; +} SDP_RepeatTime; + + + +/* A struct for a "t" field: */ +typedef struct _SDP_SessionPlayTime { + /* The time at which the session will begin: */ + time_t start_time; + + /* The time at which the session will end: */ + time_t end_time; + + /* The linked list of repreat times for this particular time: */ + SDP_LinkedList repeat_times; + + /* The next times struct in the linked list: */ + struct _SDP_SessionPlayTime *next; + + /* The previous times struct in the linked list: */ + struct _SDP_SessionPlayTime *previous; +} SDP_SessionPlayTime; + + + +/* The struct for "z" fields: */ +typedef struct _SDP_ZoneAdjustment { + /* + * At this time, there will be some sort of big shift made (e.g., time + * moving forward or backwards by an hour for DST)... + */ + time_t time; + + /* ...so adjust the repeat offests by this many seconds: */ + long offset; + + /* A pointer to the next time zone adjustment in the linked list: */ + struct _SDP_ZoneAdjustment *next; + + /* A pointer to the previous time zone adjustment in the linked list: */ + struct _SDP_ZoneAdjustment *previous; +} SDP_ZoneAdjustment; + + + +/* The "e" field struct: */ +typedef struct { + /* A string containing the encryption method (e.g., "PGP"): */ + SDP_Str method; + + /* The encryption key: */ + SDP_Str key; +} SDP_Encryption; + + + +/* Struct for session-level and media-level "a" fields: */ +typedef struct _SDP_Attribute { + /* A string containing some custom attribute name: */ + SDP_Str name; + + /* A string containing some custom attribute value: */ + SDP_Str value; + + /* A pointer to the next attrbute in the linked list: */ + struct _SDP_Attribute *next; + + /* A pointer to the previous attrbute in the linked list: */ + struct _SDP_Attribute *previous; +} SDP_Attribute; + + + +/* Struct for media description "m" fields: */ +typedef struct _SDP_MediaDescription { + /* A string containing the media type (e.g., "audio"): */ + SDP_Str media_type; + + /* The port number of where the media will be sent: */ + unsigned short port; + + /* Counting up from port, how many other ports should be used? */ + unsigned short total_ports; + + /* + * A string containing the name of the protocol to be used to deliver + * the stream (e.g., "RTP/AVP"): + */ + SDP_Str transport_protocol; + + /* A string containing the media formats: */ + SDP_Str formats; + + /* A string containing a description of the media: */ + SDP_Str media_information; + + /* + * This will store connection information for this specific piece of + * media if there was no session-level "c" field or if the connection + * used for this media differs from that used by the rest of the + * session: + */ + SDP_Connection *connection; + + /* + * This will store a suggested maximum bandwidth limit for this media + * if there was no session-level "b" field or if the bandwidth limits + * differ for this media differ than those for the entire session + */ + SDP_Bandwidth *bandwidth; + + /* + * Encryption information for the media, if there was none for the + * session or if it differs from the session's. + */ + SDP_Encryption *encryption; + + /* + * A linked list of attribute structs containing the media-level + * attributes for this piece of media: + */ + SDP_LinkedList attributes; + + /* A pointer to the next media description in the linked list: */ + struct _SDP_MediaDescription *next; + + /* A pointer to the previous media description in the linked list: */ + struct _SDP_MediaDescription *previous; +} SDP_MediaDescription; + + + +/* + * The SDP_Description structure. This contains pointers to all of the other + * structures above: + */ +typedef struct _SDP_Description { + /* The protocol version number from the "v" field: */ + int protocol_version; + + /* A struct contanining data extracted from the "o" field: */ + SDP_Owner *owner; + + /* A string containing the session name from the "s" field: */ + SDP_Str session_name; + + /* A string containing the session information from the "i" field: */ + SDP_Str session_information; + + /* A string containing the session URI from the "u" field: */ + SDP_Str uri; + + /* A linked list containing each parsed email address ("e") field: */ + SDP_LinkedList email_contacts; + + /* A linked list containing each parsed phone number ("p") field: */ + SDP_LinkedList phone_contacts; + + /* Pointer to session-level connection information from a "c" field: */ + SDP_Connection *connection; + + /* + * Pointer to session-level suggested maximum bandwidth limits from a + * "b" field: + */ + SDP_Bandwidth *bandwidth; + + /* + * A pointer to a linked list containing parsed "t" fields and the "r" + * fields that optionally follow each one: + */ + SDP_LinkedList session_play_times; + + /* + * A pointer to a linked list containing each parsed timezone + * adjustment for any repeat offsets: + */ + SDP_LinkedList zone_adjustments; + + /* The session encryption method and key: */ + SDP_Encryption *encryption; + + /* A linked list containing the session-level attributes: */ + SDP_LinkedList attributes; + + /* A linked list containing the description of each media: */ + SDP_LinkedList media_descriptions; + + /* + * If there are multiple session descriptions within a single input + * stream, then this will store a pointer to the next one in the + * linked list... + */ + struct _SDP_Description *next; + + /* ...and this will store a pointer to the previous one: */ + struct _SDP_Description *previous; +} SDP_Description; + + + +extern SDP_Description *SDP_NewDescription(void); +extern SDP_Owner *SDP_NewOwner(void); +extern SDP_EmailContact *SDP_NewEmailContact(void); +extern SDP_PhoneContact *SDP_NewPhoneContact(void); +extern SDP_Connection *SDP_NewConnection(void); +extern SDP_Bandwidth *SDP_NewBandwidth(void); +extern SDP_SessionPlayTime *SDP_NewSessionPlayTime(void); +extern SDP_RepeatTime *SDP_NewRepeatTime(void); +extern SDP_ZoneAdjustment *SDP_NewZoneAdjustment(void); +extern SDP_Encryption *SDP_NewEncryption(void); +extern SDP_Attribute *SDP_NewAttribute(void); +extern SDP_MediaDescription *SDP_NewMediaDescription(void); + +extern void SDP_SetProtocolVersion( + SDP_Description * description, + int version +); +extern int SDP_SetOwner( + SDP_Description * description, + const char * username, + const char * session_id, + const char * session_version, + const char * network_type, + const char * address_type, + const char * address +); +extern int SDP_SetUsername( + SDP_Owner * owner, + const char * username +); +extern int SDP_SetSessionID( + SDP_Owner * owner, + const char * session_id +); +extern int SDP_SetSessionVersion( + SDP_Owner * owner, + const char * session_version +); +extern int SDP_SetOwnerNetworkType( + SDP_Owner * owner, + const char * network_type +); +extern int SDP_SetOwnerAddressType( + SDP_Owner * owner, + const char * address_type +); +extern int SDP_SetOwnerAddress( + SDP_Owner * owner, + const char * address +); +extern int SDP_SetSessionName( + SDP_Description * description, + const char * session_name +); +extern int SDP_SetSessionInformation( + SDP_Description * description, + const char * session_information +); +extern int SDP_SetURI( + SDP_Description * description, + const char * uri +); +extern void SDP_AddEmailContact( + SDP_Description * description, + SDP_EmailContact * email_contact +); +extern int SDP_AddNewEmailContact( + SDP_Description * description, + const char * address, + const char * name +); +extern int SDP_SetEmailAddress( + SDP_EmailContact * email_contact, + const char * address +); +extern int SDP_SetEmailName( + SDP_EmailContact * email_contact, + const char * name +); +extern void SDP_AddPhoneContact( + SDP_Description * description, + SDP_PhoneContact * phone_contact +); +extern int SDP_AddNewPhoneContact( + SDP_Description * description, + const char * number, + const char * name +); +extern int SDP_SetPhoneNumber( + SDP_PhoneContact * phone_contact, + const char * number +); +extern int SDP_SetPhoneName( + SDP_PhoneContact * phone_contact, + const char * name +); +extern int SDP_SetConnection( + SDP_Description * description, + const char * network_type, + const char * address_type, + const char * address, + int ttl, + int total_addresses +); +extern int SDP_SetConnectionNetworkType( + SDP_Connection * connection, + const char * network_type +); +extern int SDP_SetConnectionAddressType( + SDP_Connection * connection, + const char * address_type +); +extern int SDP_SetConnectionAddress( + SDP_Connection * connection, + const char * address +); +extern void SDP_SetConnectionTTL( + SDP_Connection * connection, + int ttl +); +extern void SDP_SetTotalConnectionAddresses( + SDP_Connection * connection, + int total_addresses +); +extern int SDP_SetBandwidth( + SDP_Description * description, + const char * modifier, + long value +); +extern int SDP_SetBandwidthModifier( + SDP_Bandwidth * bandwidth, + const char * modifier +); +extern void SDP_SetBandwidthValue( + SDP_Bandwidth * bandwidth, + long value +); +extern void SDP_AddSessionPlayTime( + SDP_Description * description, + SDP_SessionPlayTime * session_play_time +); +extern int SDP_AddNewSessionPlayTime( + SDP_Description * description, + time_t start_time, + time_t end_time +); +extern void SDP_SetStartTime( + SDP_SessionPlayTime * session_play_time, + time_t start_time +); +extern void SDP_SetEndTime( + SDP_SessionPlayTime * session_play_time, + time_t end_time +); +extern void SDP_AddRepeatTime( + SDP_SessionPlayTime * session_play_time, + SDP_RepeatTime * repeat_time +); +extern int SDP_AddNewRepeatTime( + SDP_SessionPlayTime * session_play_time, + unsigned long repeat_interval, + unsigned long active_duration, + const unsigned long repeat_offsets[], + int total_offsets +); +extern void SDP_SetRepeatInterval( + SDP_RepeatTime * repeat_time, + unsigned long repeat_interval +); +extern void SDP_SetActiveDuration( + SDP_RepeatTime * repeat_time, + unsigned long active_duration +); +extern int SDP_SetRepeatOffsets( + SDP_RepeatTime * repeat_time, + const unsigned long repeat_offsets[], + int total_offsets +); +extern void SDP_AddZoneAdjustment( + SDP_Description * description, + SDP_ZoneAdjustment * zone_adjustment +); +extern int SDP_AddNewZoneAdjustment( + SDP_Description * description, + time_t time, + long offset +); +extern void SDP_SetZoneAdjustmentTime( + SDP_ZoneAdjustment * zone_adjustment, + time_t time +); +extern void SDP_SetZoneAdjustmentOffset( + SDP_ZoneAdjustment * zone_adjustment, + long offset +); +extern int SDP_SetEncryption( + SDP_Description * description, + const char * method, + const char * key +); +extern int SDP_SetEncryptionMethod( + SDP_Encryption * encryption, + const char * method +); +extern int SDP_SetEncryptionKey( + SDP_Encryption * encryption, + const char * key +); +extern void SDP_AddAttribute( + SDP_Description * description, + SDP_Attribute * attribute +); +extern int SDP_AddNewAttribute( + SDP_Description * description, + const char * name, + const char * value +); +extern int SDP_SetAttributeName( + SDP_Attribute * attribute, + const char * name +); +extern int SDP_SetAttributeValue( + SDP_Attribute * attribute, + const char * value +); +extern void SDP_AddMediaDescription( + SDP_Description * description, + SDP_MediaDescription * media_description +); +extern int SDP_AddNewMediaDescription( + SDP_Description * description, + const char * media_type, + unsigned short port, + unsigned short total_ports, + const char * transport_protocol, + const char * formats, + const char * media_information +); +extern int SDP_SetMediaType( + SDP_MediaDescription * media_description, + const char * media_type +); +extern void SDP_SetMediaPort( + SDP_MediaDescription * media_description, + unsigned short port +); +extern void SDP_SetTotalMediaPorts( + SDP_MediaDescription * media_description, + unsigned short total_ports +); +extern int SDP_SetMediaTransportProtocol( + SDP_MediaDescription * media_description, + const char * transport_protocol +); +extern int SDP_SetMediaFormats( + SDP_MediaDescription * media_description, + const char * formats +); +extern int SDP_SetMediaInformation( + SDP_MediaDescription * media_description, + const char * media_information +); +extern int SDP_SetMediaConnection( + SDP_MediaDescription * media_description, + const char * network_type, + const char * address_type, + const char * address, + int ttl, + int total_addresses +); +extern int SDP_SetMediaBandwidth( + SDP_MediaDescription * media_description, + const char * modifier, + long value +); +extern int SDP_SetMediaEncryption( + SDP_MediaDescription * media_description, + const char * method, + const char * key +); +extern void SDP_AddMediaAttribute( + SDP_MediaDescription * media_description, + SDP_Attribute * attribute +); +extern int SDP_AddNewMediaAttribute( + SDP_MediaDescription * media_description, + const char * name, + const char * value +); + +extern int SDP_GetProtocolVersion(SDP_Description *description); +extern SDP_Owner *SDP_GetOwner(SDP_Description *description); +extern const char *SDP_GetUsername(SDP_Owner *owner); +extern const char *SDP_GetSessionID(SDP_Owner *owner); +extern const char *SDP_GetSessionVersion(SDP_Owner *owner); +extern const char *SDP_GetOwnerNetworkType(SDP_Owner *owner); +extern const char *SDP_GetOwnerAddressType(SDP_Owner *owner); +extern const char *SDP_GetOwnerAddress(SDP_Owner *owner); +extern const char *SDP_GetSessionName(SDP_Description *description); +extern const char *SDP_GetSessionInformation(SDP_Description *description); +extern const char *SDP_GetURI(SDP_Description *description); +extern SDP_EmailContact *SDP_GetEmailContacts(SDP_Description *description); +extern const char *SDP_GetEmailAddress(SDP_EmailContact *email_contact); +extern const char *SDP_GetEmailName(SDP_EmailContact *email_contact); +extern void SDP_RemoveEmailContact( + SDP_Description * description, + SDP_EmailContact * email_contact +); +extern SDP_PhoneContact *SDP_GetPhoneContacts(SDP_Description *description); +extern const char *SDP_GetPhoneNumber(SDP_PhoneContact *phone_contact); +extern const char *SDP_GetPhoneName(SDP_PhoneContact *phone_contact); +extern void SDP_RemovePhoneContact( + SDP_Description * description, + SDP_PhoneContact * phone_contact +); +extern SDP_Connection *SDP_GetConnection(SDP_Description *description); +extern const char *SDP_GetConnectionNetworkType(SDP_Connection *connection); +extern const char *SDP_GetConnectionAddressType(SDP_Connection *connection); +extern const char *SDP_GetConnectionAddress(SDP_Connection *connection); +extern int SDP_GetConnectionTTL(SDP_Connection *connection); +extern int SDP_GetTotalConnectionAddresses(SDP_Connection *connection); +extern SDP_Bandwidth *SDP_GetBandwidth(SDP_Description *description); +extern const char *SDP_GetBandwidthModifier(SDP_Bandwidth *bandwidth); +extern long SDP_GetBandwidthValue(SDP_Bandwidth *bandwidth); +extern SDP_SessionPlayTime *SDP_GetSessionPlayTimes( + SDP_Description *description +); +extern time_t SDP_GetStartTime(SDP_SessionPlayTime *session_play_time); +extern time_t SDP_GetEndTime(SDP_SessionPlayTime *session_play_time); +extern SDP_RepeatTime *SDP_GetRepeatTimes( + SDP_SessionPlayTime *session_play_time +); +extern unsigned long SDP_GetRepeatInterval(SDP_RepeatTime *repeat_time); +extern unsigned long SDP_GetActiveDuration(SDP_RepeatTime *repeat_time); +extern unsigned long *SDP_GetRepeatOffsets(SDP_RepeatTime *repeat_time); +extern int SDP_GetTotalRepeatOffsets(SDP_RepeatTime *repeat_time); +extern void SDP_RemoveRepeatTime( + SDP_SessionPlayTime * session_play_times, + SDP_RepeatTime * repeat_time +); +extern void SDP_RemoveSessionPlayTime( + SDP_Description * description, + SDP_SessionPlayTime * session_play_time +); +extern SDP_ZoneAdjustment *SDP_GetZoneAdjustments(SDP_Description *description); +extern time_t SDP_GetZoneAdjustmentTime(SDP_ZoneAdjustment *zone_adjustment); +extern long SDP_GetZoneAdjustmentOffset(SDP_ZoneAdjustment *zone_adjustment); +extern void SDP_RemoveZoneAdjustment( + SDP_Description * description, + SDP_ZoneAdjustment * zone_adjustment +); +extern SDP_Encryption *SDP_GetEncryption(SDP_Description *description); +extern const char *SDP_GetEncryptionMethod(SDP_Encryption *encryption); +extern const char *SDP_GetEncryptionKey(SDP_Encryption *encryption); +extern SDP_Attribute *SDP_GetAttributes(SDP_Description *description); +extern const char *SDP_GetAttributeName(SDP_Attribute *attribute); +extern const char *SDP_GetAttributeValue(SDP_Attribute *attribute); +extern void SDP_RemoveAttribute( + SDP_Description * description, + SDP_Attribute * attribute +); +extern SDP_MediaDescription *SDP_GetMediaDescriptions( + SDP_Description *description +); +extern const char *SDP_GetMediaType(SDP_MediaDescription *media_description); +extern unsigned short SDP_GetMediaPort(SDP_MediaDescription *media_description); +extern unsigned short SDP_GetTotalMediaPorts( + SDP_MediaDescription *media_description +); +extern const char *SDP_GetMediaTransportProtocol( + SDP_MediaDescription *media_description +); +extern const char *SDP_GetMediaFormats(SDP_MediaDescription *media_description); +extern const char *SDP_GetMediaInformation( + SDP_MediaDescription *media_description +); +extern SDP_Connection *SDP_GetMediaConnection( + SDP_MediaDescription *media_description +); +extern SDP_Bandwidth *SDP_GetMediaBandwidth( + SDP_MediaDescription *media_description +); +extern SDP_Encryption *SDP_GetMediaEncryption( + SDP_MediaDescription *media_description +); +extern SDP_Attribute *SDP_GetMediaAttributes( + SDP_MediaDescription *media_description +); +extern void SDP_RemoveMediaDescription( + SDP_Description * description, + SDP_MediaDescription * media_description +); + +/* We also provide more descriptive versions of the Get/Set list macros: */ +#define SDP_GetNextDescription SDP_GetNext +#define SDP_GetPreviousDescription SDP_GetPrevious +#define SDP_GetNextEmailContact SDP_GetNext +#define SDP_GetPreviousEmailContact SDP_GetPrevious +#define SDP_GetNextPhoneContact SDP_GetNext +#define SDP_GetPreviousPhoneContact SDP_GetPrevious +#define SDP_GetNextSessionPlayTime SDP_GetNext +#define SDP_GetPreviousSessionPlayTime SDP_GetPrevious +#define SDP_GetNextRepeatTime SDP_GetNext +#define SDP_GetPreviousRepeatTime SDP_GetPrevious +#define SDP_GetNextZoneAdjustment SDP_GetNext +#define SDP_GetPreviousZoneAdjustment SDP_GetPrevious +#define SDP_GetNextAttribute SDP_GetNext +#define SDP_GetPreviousAttribute SDP_GetPrevious +#define SDP_GetNextMediaDescription SDP_GetNext + +#define SDP_SetNextDescription SDP_SetNext +#define SDP_SetPreviousDescription SDP_SetPrevious +#define SDP_SetNextEmailContact SDP_SetNext +#define SDP_SetPreviousEmailContact SDP_SetPrevious +#define SDP_SetNextPhoneContact SDP_SetNext +#define SDP_SetPreviousPhoneContact SDP_SetPrevious +#define SDP_SetNextSessionPlayTime SDP_SetNext +#define SDP_SetPreviousSessionPlayTime SDP_SetPrevious +#define SDP_SetNextRepeatTime SDP_SetNext +#define SDP_SetPreviousRepeatTime SDP_SetPrevious +#define SDP_SetNextZoneAdjustment SDP_SetNext +#define SDP_SetPreviousZoneAdjustment SDP_SetPrevious +#define SDP_SetNextAttribute SDP_SetNext +#define SDP_SetPreviousAttribute SDP_SetPrevious +#define SDP_SetNextMediaDescription SDP_SetNext + +extern void SDP_DestroyDescriptions(SDP_Description *descriptions); +extern void SDP_DestroyDescription(SDP_Description *description); +extern void SDP_DestroyOwner(SDP_Owner *owner); +extern void SDP_DestroyEmailContacts(SDP_Description *description); +extern void SDP_DestroyEmailContact(SDP_EmailContact *email_contact); +extern void SDP_DestroyPhoneContacts(SDP_Description *description); +extern void SDP_DestroyPhoneContact(SDP_PhoneContact *phone_contact); +extern void SDP_DestroyConnection(SDP_Connection *connection); +extern void SDP_DestroyBandwidth(SDP_Bandwidth *bandwidth); +extern void SDP_DestroySessionPlayTimes(SDP_Description *description); +extern void SDP_DestroySessionPlayTime(SDP_SessionPlayTime *session_play_time); +extern void SDP_DestroyRepeatTimes(SDP_SessionPlayTime *session_play_time); +extern void SDP_DestroyRepeatTime(SDP_RepeatTime *repeat_time); +extern void SDP_DestroyZoneAdjustments(SDP_Description *description); +extern void SDP_DestroyZoneAdjustment(SDP_ZoneAdjustment *zone_adjustment); +extern void SDP_DestroyEncryption(SDP_Encryption *encryption); +extern void SDP_DestroyAttributes(SDP_Description *description); +extern void SDP_DestroyAttribute(SDP_Attribute *attribute); +extern void SDP_DestroyMediaDescriptions(SDP_Description *description); +extern void SDP_DestroyMediaDescription(SDP_MediaDescription *media_description); +extern void SDP_DestroyMediaAttributes(SDP_MediaDescription *media_description); + + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdp_lib/src/SDP_Error.c b/src/sdp_lib/src/SDP_Error.c new file mode 100644 index 0000000..3440896 --- /dev/null +++ b/src/sdp_lib/src/SDP_Error.c @@ -0,0 +1,226 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#include +#include +#include +#include "SDP_Error.h" +#include "SDP_Utility.h" + +/* + * The size of the global string used to store a description of the last error + * to occur: + */ +#define ERROR_STRING_SIZE 512 + + + + + + + +/* The error code of the last error to occur: */ +static SDP_Error _last_error = SDP_NO_ERROR; + +/* The string containing the error message of the last error to occur: */ +static char _last_error_string[ERROR_STRING_SIZE]; + + + +/* + * If this symbol is defined, then these two default error handlers will be + * registered: + */ +#ifdef SINISTERSDP_REGISTER_DEFAULT_ERROR_HANDLERS + +/* Default error handlers: */ +static void _DefaultFatalErrorHandler( + SDP_Error error_code, + const char * error_string +); +static int _DefaultNonFatalErrorHandler( + SDP_Error error_code, + const char * error_string +); + +/* The callback for fatal, non-recoverable errors: */ +static SDP_FatalErrorHandler _fatal_error_handler = + _DefaultFatalErrorHandler; + +/* The callback for non-fatal, recoverable errors: */ +static SDP_NonFatalErrorHandler _non_fatal_error_handler = + _DefaultNonFatalErrorHandler; + +#else + +static SDP_FatalErrorHandler _fatal_error_handler = NULL; +static SDP_NonFatalErrorHandler _non_fatal_error_handler = NULL; + +#endif + + + +/* + * If some function raises an error, should either of the appropriate error + * handlers above be invoked? + */ +static int _use_error_handlers = 1; + + + + + +int SDP_ErrorRaised(void) +{ + return _last_error ? 1 : 0; +} + + + + + +SDP_Error SDP_GetLastError(void) +{ + return _last_error; +} + + + + + +const char *SDP_GetLastErrorString(void) +{ + return _last_error_string; +} + + + + + +void SDP_SetFatalErrorHandler(SDP_FatalErrorHandler handler) +{ + _fatal_error_handler = handler; +} + + + + + +void SDP_SetNonFatalErrorHandler(SDP_NonFatalErrorHandler handler) +{ + _non_fatal_error_handler = handler; +} + + + + + +void SDP_UseHandlersForErrors(int use_handlers) +{ + _use_error_handlers = use_handlers ? 1 : 0; +} + + + + + +void SDP_RaiseFatalError( + SDP_Error code, + const char * format, + ...) +{ + va_list args; + + SDP_AssertTrue(code); + SDP_AssertNotNull(format); + + _last_error = code; + + va_start(args, format); + vsnprintf( + _last_error_string, sizeof(_last_error_string), format, args + ); + va_end(args); + + if (_use_error_handlers && _fatal_error_handler) + (*_fatal_error_handler)(_last_error, _last_error_string); +} + + + + + +int SDP_RaiseNonFatalError( + SDP_Error code, + const char * format, + ...) +{ + va_list args; + + SDP_AssertTrue(code); + SDP_AssertNotNull(format); + + _last_error = code; + + va_start(args, format); + vsnprintf( + _last_error_string, sizeof(_last_error_string), format, args + ); + va_end(args); + + /* + * We use the handler's return value as a flag to tell us whether or + * not we should keep going even after encountering an error. + * + * If there's no registered handler, then just stop: + */ + if (_use_error_handlers && _non_fatal_error_handler) + return (*_non_fatal_error_handler)( + _last_error, _last_error_string + ); + else + return SDP_STOP_AFTER_ERROR; +} + + + + + +#ifdef SINISTERSDP_REGISTER_DEFAULT_ERROR_HANDLERS + +static void _DefaultFatalErrorHandler( + SDP_Error error_code, + const char * error_string) +{ + fprintf(stderr, "Fatal error: %s\n", error_string); + + /* Exit the entire process: */ + exit(EXIT_FAILURE); +} + + + + + +static int _DefaultNonFatalErrorHandler( + SDP_Error error_code, + const char * error_string) +{ + fprintf(stderr, "Error: %s\n", error_string); + + /* Force the caller to exit prematurely: */ + return SDP_STOP_AFTER_ERROR; +} + +#endif diff --git a/src/sdp_lib/src/SDP_Error.h b/src/sdp_lib/src/SDP_Error.h new file mode 100755 index 0000000..44d9338 --- /dev/null +++ b/src/sdp_lib/src/SDP_Error.h @@ -0,0 +1,111 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SDP_ERROR_INCLUDED +#define SDP_ERROR_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/* + * We put SDP_OS_ERROR_STRING in parenthesis so we can treat it like a "char *" + * variable and dereference it (e.g., "*SDP_OS_ERROR_STRING == '!'"): + */ +#define SDP_OS_ERROR_CODE errno +#define SDP_OS_ERROR_STRING (strerror(SDP_OS_ERROR_CODE)) + + + + + +typedef enum { + /* No error; nothing bad has happened! */ + SDP_NO_ERROR = 0, + + /* Some sort of error occurred; this is used mostly for testing: */ + SDP_ERR_GENERIC = 1, + + /* + * These errors are fatal, non-recoverable, meaning that the function + * that riases them must return immediately and cannot continue + * execution: + */ + SDP_ERR_OUT_OF_MEMORY = 1000, + SDP_ERR_FILE_OPEN_FAILED, + + /* + * These errors are non-fatal, recoverable parser errors; the parser + * can either stop or keep going depending on the return value of the + * error handler: + */ + SDP_ERR_MALFORMED_LINE = 2000, + SDP_ERR_MALFORMED_V_FIELD, + SDP_ERR_MALFORMED_O_FIELD, + SDP_ERR_MALFORMED_E_FIELD, + SDP_ERR_MALFORMED_P_FIELD, + SDP_ERR_MALFORMED_C_FIELD, + SDP_ERR_MALFORMED_B_FIELD, + SDP_ERR_MALFORMED_T_FIELD, + SDP_ERR_MALFORMED_R_FIELD, + SDP_ERR_MALFORMED_Z_FIELD, + SDP_ERR_MALFORMED_K_FIELD, + SDP_ERR_MALFORMED_A_FIELD, + SDP_ERR_MALFORMED_M_FIELD, + SDP_ERR_INVALID_TYPE_CHARACTER, + SDP_ERR_MULTIPLE_UNIQUE_FIELDS, + SDP_ERR_FIELDS_OUT_OF_SEQUENCE +} SDP_Error; + +/* Function pointer typedefs for each type of error handler: */ +typedef void (*SDP_FatalErrorHandler)( + SDP_Error error_code, + const char * error_string +); +typedef int (*SDP_NonFatalErrorHandler)( + SDP_Error error_code, + const char * error_string +); + + + +extern int SDP_ErrorRaised(void); +extern SDP_Error SDP_GetLastError(void); +extern const char *SDP_GetLastErrorString(void); +extern void SDP_SetFatalErrorHandler(SDP_FatalErrorHandler handler); +extern void SDP_SetNonFatalErrorHandler(SDP_NonFatalErrorHandler handler); +extern void SDP_UseHandlersForErrors(int use_handlers); +extern void SDP_RaiseFatalError( + SDP_Error code, + const char * format, + ... +); +extern int SDP_RaiseNonFatalError( + SDP_Error code, + const char * format, + ... +); + + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdp_lib/src/SDP_EventStreamParser.c b/src/sdp_lib/src/SDP_EventStreamParser.c new file mode 100644 index 0000000..1a4685b --- /dev/null +++ b/src/sdp_lib/src/SDP_EventStreamParser.c @@ -0,0 +1,827 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + *------------------------------------------------------------------------------ + * + * This file contains routines that implement the lower-level SDP event stream + * parser. See SinisterSdpParser.html for documentation. + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "SDP_EventStreamParser.h" +#include "SDP_StreamTokenizer.h" +#include "SDP_Utility.h" + + + + + + + +/* This does the actual parsing: */ +static int _ParseStream(SDP_Parser *parser); + +/* These routines invoke user's registered handlers: */ +static int _InvokeStartHandler(SDP_Parser *parser); +static int _InvokeStartDescriptionHandler(SDP_Parser *parser); +static int _InvokeFieldHandler(SDP_Parser *parser); +static int _InvokeEndDescriptionHandler(SDP_Parser *parser); +static void _InvokeEndHandler( + SDP_Parser * parser, + int rv +); + + + + + +SDP_Parser *SDP_NewParser(void) +{ + SDP_Parser *parser = (SDP_Parser *) SDP_Allocate(sizeof(SDP_Parser)); + if (parser == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to create a new SDP " + "parser: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + memset(parser, 0, sizeof(SDP_Parser)); + + /* Set the default state and initialize the token buffer too: */ + parser->state = SDP_STOPPED; + parser->stream_tokenizer = SDP_NewStreamTokenizer(); + if (parser->stream_tokenizer == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for the SDP parser's " + "tokenizer: %s.", + SDP_OS_ERROR_STRING + ); + return NULL; + } + + return parser; +} + + + + + +int SDP_EventStreamParse( + SDP_Parser * parser, + const char * string) +{ + SDP_AssertNotNull(parser); + SDP_AssertNotNull(string); + + SDP_UseStringAsStream(parser->stream_tokenizer, string); + + return _ParseStream(parser); +} + + + + + +int SDP_EventStreamParseFile( + SDP_Parser * parser, + const char * filename) +{ + FILE *file; + int rv; + + SDP_AssertNotNull(parser); + SDP_AssertNotNull(filename); + + file = fopen(filename, "r"); + if (file == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_FILE_OPEN_FAILED, + "Couldn't open file \"%s\" to parse it as a stream: " + "%s.", + filename, + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + SDP_UseFileAsStream(parser->stream_tokenizer, file); + + rv = _ParseStream(parser); + + fclose(file); + + return rv; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseStream(parser) + * + * Purpose + * This function parses the actual stream, invoking registered + * event handlers when the events occur. A stream must be set for + * the internal "stream_tokenizer" struct using one of the + * SDP_Use*AsStream() functions before calling this function. + * + * Parameters + * parser - A pointer to an SDP_Parser struct. + * + */ + +static int _ParseStream(SDP_Parser *parser) +{ + /* The current token: */ + char *token; + + /* The type of the field being parsed: */ + int type_char; + + /* + * After we break out of the loop below, if something went wrong, then + * this will be false: + */ + int rv = SDP_SUCCESS; + + + SDP_AssertNotNull(parser); + + /* + * Before we start parsing, we need to invoke any specified start + * handler: + */ + rv = _InvokeStartHandler(parser); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + /* Now parse each newline-delimited token from the specified stream: */ + parser->state = SDP_RUNNING; + parser->current_line_number = 0; + while (1) + { + ++parser->current_line_number; + + /* Reset these two for the next token: */ + parser->current_field_type = '\0'; + parser->current_field = NULL; + + /* Get the next CR, LF, or CRLF delimited token: */ + rv = SDP_GetNextToken(parser->stream_tokenizer, &token); + if (SDP_FAILED(rv)) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to get the next " + "line from the stream: %s.", + SDP_OS_ERROR_STRING + ); + break; + } + + /* No more tokens? */ + if (token == NULL) + break; + + /* + * Check for an empty token, a newline that was followed right + * away by another newline: + */ + if (*token == '\0') + { + if (parser->state == SDP_PARSING_DESCRIPTION) + { + /* + * If it's a blank line and we're already + * parsing a description, then take it as the + * end of the description: + */ + rv = _InvokeEndDescriptionHandler(parser); + + /* We're outside of any description, so... */ + parser->state = SDP_RUNNING; + + if (SDP_SUCCEEDED(rv)) + continue; + else + break; + } + else + { + /* + * Keep going to till we find a non-blank + * line: + */ + continue; + } + } + + /* Make sure the field is in the valid "x=value" format: */ + if (!isalpha(*token) || *(token + 1) != '=') + { + rv = SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_LINE, + "Line %d is malformed; it doesn't contain a " + "proper \"x=value\" sequence, and must be " + "discarded.", + parser->current_line_number + ); + if (SDP_SUCCEEDED(rv)) + continue; + else + break; + } + + /* Get the type character as an int so we can test it: */ + type_char = *token; + + /* Make sure its in range: */ + if (type_char < 0 || type_char > 255) + { + rv = SDP_RaiseNonFatalError( + SDP_ERR_INVALID_TYPE_CHARACTER, + "Line %d contains a type character with an " + "ordinal value \"%d\", which is out of range; " + "isn't 8-bit ISO Latin-1.", + parser->current_line_number, + type_char + ); + if (SDP_SUCCEEDED(rv)) + continue; + else + break; + } + + /* + * Cast the type character, just to be safe, cause we're gonna + * use it to subscript an array later on: + */ + parser->current_field_type = (unsigned char) type_char; + + /* Move beyond the "x=" to get the field value: */ + parser->current_field = token += 2; + + /* + * The standard doesn't allow for custom fields; it defines a + * dozen or so fields and their associated type characters, and + * allows for extensions via "a" fields: + */ + if (!SDP_IsKnownFieldType(parser->current_field_type)) + { + rv = SDP_RaiseNonFatalError( + SDP_ERR_INVALID_TYPE_CHARACTER, + "Line %d contains a \"%c\" field. The standard " + "has defined no such field, and mandates user-" + "defined extensions to be created using \"a\" " + "fields instead; it has been discarded.", + parser->current_line_number, + parser->current_field_type + ); + if (SDP_SUCCEEDED(rv)) + continue; + else + break; + } + + /* A "v" field signifies the start of an SDP description */ + if (parser->current_field_type == 'v') + { + if (parser->state == SDP_PARSING_DESCRIPTION) + { + /* + * If we've already parsed a description, then + * the "v" field signals the end of the current + * description and the start of a new one: + */ + rv = _InvokeEndDescriptionHandler(parser); + if (SDP_FAILED(rv)) + break; + + /* + * We need to reset the list of fields we've + * seen, since we're starting on a new session + * description with new fields: + */ + memset( + parser->fields_seen, + 0, + sizeof(parser->fields_seen) + ); + } + else + { + parser->state = SDP_PARSING_DESCRIPTION; + } + + ++parser->current_description_number; + + /* + * Invoke the start handler for the start of this new + * description: + */ + rv = _InvokeStartDescriptionHandler(parser); + if (SDP_FAILED(rv)) + break; + } + else + { + /* + * Make sure that if it isn't a "v=" field, that we've + * *already* encountered one: + */ + if (!SDP_FieldEncountered(parser, 'v') + || parser->state != SDP_PARSING_DESCRIPTION) + { + rv = SDP_RaiseNonFatalError( + SDP_ERR_FIELDS_OUT_OF_SEQUENCE, + "Line %d contains a \"%c\" field, but " + "no \"v\" field has been encountered " + "yet; this doesn't seem to belong " + "to any description and it has been " + "discarded", + parser->current_line_number, + parser->current_field_type + ); + if (SDP_SUCCEEDED(rv)) + continue; + else + break; + } + } + + /* + * Some fields only appear once in an entire session + * description (like "v" or "o"), whereas others can appear + * multiple times (like "a" or "t"): + */ + if (SDP_FieldEncountered(parser, parser->current_field_type) + && (parser->current_field_type == 'o' + || parser->current_field_type == 's' + || parser->current_field_type == 'u' + || parser->current_field_type == 'z')) + { + rv = SDP_RaiseNonFatalError( + SDP_ERR_MULTIPLE_UNIQUE_FIELDS, + "Line %d contains a \"%c\" field, but a " + "\"%c\" field was already encountered. There " + "should be only one \"%c\" field per-session " + "description.", + parser->current_line_number, + parser->current_field_type, + parser->current_field_type, + parser->current_field_type + ); + if (rv) + continue; + else + break; + } + + /* + * This looks bad, and the cast really isn't needed since we + * already casted it and made sure it was in range before that, + * but gcc warns under -Wall if we take it out: + */ + ++parser->fields_seen[ + (unsigned char) parser->current_field_type + ]; + + + + /* + * Now that we've extracted the field type and field value and + * we've performed some semblance of validation, try to invoke + * the user's field handler to handle the field: + */ + rv = _InvokeFieldHandler(parser); + if (SDP_FAILED(rv)) + break; + } + + /* + * Now try to invoke the end description handler one last time, unless + * some error occurred, and capture its return status: + */ + if (parser->state == SDP_PARSING_DESCRIPTION && SDP_SUCCEEDED(rv)) + rv = _InvokeEndDescriptionHandler(parser); + + /* Reset the state: */ + parser->state = SDP_STOPPED; + + /* Now the end handler, since we're done parsing: */ + _InvokeEndHandler(parser, rv); + + return rv; +} + + + + + +void SDP_SetStartHandler( + SDP_Parser * parser, + SDP_StartHandler handler) +{ + SDP_AssertNotNull(parser); + + parser->start_handler = handler; +} + + + + + +void SDP_SetStartDescriptionHandler( + SDP_Parser * parser, + SDP_StartDescriptionHandler handler) +{ + SDP_AssertNotNull(parser); + + parser->start_description_handler = handler; +} + + + + + +void SDP_SetFieldHandler( + SDP_Parser * parser, + SDP_FieldHandler handler) +{ + SDP_AssertNotNull(parser); + + parser->field_handler = handler; +} + + + + + +void SDP_SetEndDescriptionHandler( + SDP_Parser * parser, + SDP_EndDescriptionHandler handler) +{ + SDP_AssertNotNull(parser); + + parser->end_description_handler = handler; +} + + + + + +void SDP_SetEndHandler( + SDP_Parser * parser, + SDP_EndHandler handler) +{ + SDP_AssertNotNull(parser); + + parser->end_handler = handler; +} + + + + + +void SDP_SetUserData( + SDP_Parser * parser, + void * user_data) +{ + SDP_AssertNotNull(parser); + + parser->user_data = user_data; +} + + + + + +SDP_StartHandler SDP_GetStartHandler(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->start_handler; +} + + + + + +SDP_StartDescriptionHandler SDP_GetStartDescriptionHandler(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->start_description_handler; +} + + + + + +SDP_FieldHandler SDP_GetFieldHandler(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->field_handler; +} + + + + + +SDP_EndDescriptionHandler SDP_GetEndDescriptionHandler(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->end_description_handler; +} + + + + + +SDP_EndHandler SDP_GetEndHandler(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->end_handler; +} + + + + + +void *SDP_GetUserData(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->user_data; +} + + + + + +int SDP_GetCurrentLineNumber(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->current_line_number; +} + + + + + +int SDP_GetCurrentDescriptionNumber(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->current_description_number; +} + + + + + +char SDP_GetCurrentFieldType(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->current_field_type; +} + + + + + +char *SDP_GetCurrentField(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + return parser->current_field; +} + + + + + +int SDP_FieldEncountered( + SDP_Parser * parser, + char field_type) +{ + SDP_AssertNotNull(parser); + SDP_Assert(field_type >= 0); + + return parser->fields_seen[(unsigned char) field_type]; +} + + + + + +void SDP_DestroyParser(SDP_Parser *parser) +{ + SDP_AssertNotNull(parser); + + if (parser->stream_tokenizer) + SDP_DestroyStreamTokenizer(parser->stream_tokenizer); + + SDP_Destroy(parser); +} + + + + + +/******************************************************************************* + * + * Name + * _InvokeStartHandler(parser) + * + * Purpose + * This function invokes any registered start handler with a + * pointer to the parser struct as the first argument and a + * pointer to any specified user data as the second argument. + * + * It returns the return value of the user's handler, or just true + * if no handler is registered. + * + * Parameters + * parser - A pointer to an SDP_Parser struct. + * + */ + +static int _InvokeStartHandler(SDP_Parser *parser) +{ + if (parser->start_handler) + return parser->start_handler(parser, parser->user_data); + else + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _InvokeStartDescriptionHandler(parser) + * + * Purpose + * This function invokes any registered start-of-description + * handler with a pointer to the parser struct as the first + * argument, the number of the description that just started as + * the second argument, and a pointer to any specified user data + * as the third argument. + * + * It returns the return value of the user's handler, or just true + * if no handler is registered. + * + * Parameters + * parser - A pointer to an SDP_Parser struct. + * + */ + +static int _InvokeStartDescriptionHandler(SDP_Parser *parser) +{ + if (parser->start_description_handler) + return parser->start_description_handler( + parser, + parser->current_description_number, + parser->user_data + ); + else + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _InvokeFieldHandler(parser) + * + * Purpose + * This function invokes any registered field handler with a + * pointer to the parser struct as the first argument, the type + * character of the field to handle as the seocnd argument, a + * pointer to a string containing the value of the field to + * handler as the third argument, and a pointer to any specified + * user data as the fourth argument. + * + * It returns the return value of the user's handler, or just true + * if no handler is registered. + * + * Parameters + * parser - A pointer to an SDP_Parser struct. + * + */ + +static int _InvokeFieldHandler(SDP_Parser *parser) +{ + if (parser->field_handler) + return parser->field_handler( + parser, + parser->current_field_type, + parser->current_field, + parser->user_data + ); + else + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _InvokeEndDescriptionHandler(parser) + * + * Purpose + * This function invokes any registered end-of-description handler + * with a pointer to the parser struct as the first argument, the + * number of the description that just ended as the second + * argument, and a pointer to any specified user data as the third + * argument. + * + * It returns the return value of the user's handler, or just true + * if no handler is registered. + * + * Parameters + * parser - A pointer to an SDP_Parser struct. + * + */ + +static int _InvokeEndDescriptionHandler(SDP_Parser *parser) +{ + if (parser->end_description_handler) + return parser->end_description_handler( + parser, + parser->current_description_number, + parser->user_data + ); + else + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _InvokeEndHandler(parser, result) + * + * Purpose + * This function invokes any registered end handler with a pointer + * to the parser struct as the first argument, the result of + * parsing (success or failure) as the second argument, and a + * pointer to any specified user data as the third argument. + * + * Parameters + * parser - A pointer to an SDP_Parser struct. + * result - The result of _ParseStream; true or false, success or + * failure. This will be passed on to the user's end + * handler as the second argument. + * + */ + +static void _InvokeEndHandler( + SDP_Parser * parser, + int result) +{ + if (parser->end_handler) + parser->end_handler(parser, result, parser->user_data); +} diff --git a/src/sdp_lib/src/SDP_EventStreamParser.h b/src/sdp_lib/src/SDP_EventStreamParser.h new file mode 100644 index 0000000..dd40e07 --- /dev/null +++ b/src/sdp_lib/src/SDP_EventStreamParser.h @@ -0,0 +1,200 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SDP_EVENT_STREAM_PARSER_INCLUDED +#define SDP_EVENT_STREAM_PARSER_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include "SDP_Error.h" +#include "SDP_StreamTokenizer.h" +#include "SDP_Utility.h" + + + + + +/* + * We declar this out here first, instead of just wrapping the actual structure + * declaration in a typedef because the function pointer typedefs below need + * to take this struct as an argument, but the struct needs to contain function + * pointers of those types (it's a chicken and egg thing): + */ +struct _SDP_Parser; + +/* The various stream event handlers; */ +typedef int (*SDP_StartHandler)( + struct _SDP_Parser * parser, + void * user_data +); +typedef int (*SDP_StartDescriptionHandler)( + struct _SDP_Parser * parser, + int current_description_number, + void * user_data +); +typedef int (*SDP_FieldHandler)( + struct _SDP_Parser * parser, + char type, + const char * value, + void * user_data +); +typedef int (*SDP_EndDescriptionHandler)( + struct _SDP_Parser * parser, + int current_description_number, + void * user_data +); +typedef void (*SDP_EndHandler)( + struct _SDP_Parser * parser, + int result, + void * user_data +); + +typedef struct _SDP_Parser { + /* + * The state of the parser (SDP_STOPPED == doing nothing, + * SDP_RUNNING == reading lines and waiting for the first "v=" field to + * sink its teeth into, SDP_PARSING_SESSION_DESCRIPTION == parsing + * SDP fields): + */ + enum { + SDP_STOPPED, + SDP_RUNNING, + SDP_PARSING_DESCRIPTION + } state; + + /* + * A pointer to the tokenizer we'll use to chop up the stream into + * individual newline-delimited SDP fields: + */ + SDP_StreamTokenizer *stream_tokenizer; + + /* The number of the line being parsed at the moment */ + int current_line_number; + + /* + * The number of the current description being parsed (1 for the first + * description, 2 for the second...): + */ + int current_description_number; + + /* The type character of the field being parsed at the moment: */ + char current_field_type; + + /* + * A pointer to a string containing the current SDP field value + * (everything after the "=" sign): + */ + char *current_field; + + /* + * For a particular description, this array stores the number of times + * each field has been encountered. It's indexed using type characters + * (e.g, parser->fields_seen['o'] > 1). Everytime a "v" field is + * encountered, designating the start of another description, this + * array is reset: + */ + int fields_seen[256]; + + /* The handlers for the event stream parser: */ + SDP_StartHandler start_handler; + SDP_StartDescriptionHandler start_description_handler; + SDP_FieldHandler field_handler; + SDP_EndDescriptionHandler end_description_handler; + SDP_EndHandler end_handler; + + /* + * A pointer to *something* the user wants us to pass to the first five + * event handlers when we call them: + */ + void *user_data; +} SDP_Parser; + + + +extern SDP_Parser *SDP_NewParser(void); + +extern int SDP_EventStreamParse( + SDP_Parser * parser, + const char * string +); +extern int SDP_EventStreamParseFile( + SDP_Parser * parser, + const char * filename +); + +extern void SDP_SetStartHandler( + SDP_Parser * parser, + SDP_StartHandler handler +); +extern void SDP_SetStartDescriptionHandler( + SDP_Parser * parser, + SDP_StartDescriptionHandler handler +); +extern void SDP_SetFieldHandler( + SDP_Parser * parser, + SDP_FieldHandler handler +); +extern void SDP_SetEndDescriptionHandler( + SDP_Parser * parser, + SDP_EndDescriptionHandler handler +); +extern void SDP_SetEndHandler( + SDP_Parser * parser, + SDP_EndHandler handler +); +extern void SDP_SetUserData( + SDP_Parser * parser, + void * user_data +); + +extern SDP_StartHandler SDP_GetStartHandler( + SDP_Parser *parser +); +extern SDP_StartDescriptionHandler SDP_GetStartDescriptionHandler( + SDP_Parser *parser +); +extern SDP_FieldHandler SDP_GetFieldHandler( + SDP_Parser *parser +); +extern SDP_EndDescriptionHandler SDP_GetEndDescriptionHandler( + SDP_Parser *parser +); +extern SDP_EndHandler SDP_GetEndHandler( + SDP_Parser *parser +); +extern void *SDP_GetUserData(SDP_Parser *parser); + +extern int SDP_GetCurrentLineNumber(SDP_Parser *parser); +extern int SDP_GetCurrentDescriptionNumber(SDP_Parser *parser); +extern char SDP_GetCurrentFieldType(SDP_Parser *parser); +extern char *SDP_GetCurrentField(SDP_Parser *parser); +extern int SDP_FieldEncountered( + SDP_Parser * parser, + char field_type +); + +extern void SDP_DestroyParser(SDP_Parser *parser); + + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdp_lib/src/SDP_Generator.c b/src/sdp_lib/src/SDP_Generator.c new file mode 100644 index 0000000..01eef45 --- /dev/null +++ b/src/sdp_lib/src/SDP_Generator.c @@ -0,0 +1,1472 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * This file contains routines that implement the session description + * generator. See SDP_Generator.html for documentation. + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include "SDP_Error.h" +#include "SDP_Description.h" +#include "SDP_Generator.h" +#include "SDP_Str.h" +#include "SDP_Utility.h" + +/* + * This is used to ensure _Generate() never gets passed a NULL pointer as the + * replacement argument for a "%s" sequence in the format; always a real + * pointer to *some* string, even just an empty one: + */ +#define STRINGIFY(_string_) ((_string_) ? _string_ : "") + +/* This converts a time_t to a Network Time Protocol seconds timestamp: */ +#define OS_TIME_TO_NETWORK_TIME(_time_) \ + ((_time_) ? ((unsigned long) (_time_)) + 2208988800UL : 0UL) + + + + + + + +static int _DescriptionAsString( + SDP_Generator * generator, + SDP_Description * description +); + +char *SDP_OutputDescriptionsToString(SDP_Description *descriptions) +{ + SDP_Generator *generator; + SDP_Description *description; + char *generated_descriptions; + int rv; + + SDP_AssertNotNull(descriptions); + + generator = SDP_NewGenerator(); + if (generator == NULL) + return NULL; + + description = descriptions; + while (description) + { + rv = _DescriptionAsString(generator, description); + if (SDP_FAILED(rv)) + { + SDP_DestroyGenerator(generator); + return NULL; + } + + description = SDP_GetNextDescription(description); + } + + generated_descriptions = SDP_StrDup(SDP_GetGeneratedOutput(generator)); + + SDP_DestroyGenerator(generator); + + return generated_descriptions; +} + + + + + +char *SDP_OutputDescriptionToString(SDP_Description *description) +{ + SDP_Generator *generator; + char *generated_description; + int rv; + + SDP_AssertNotNull(description); + + generator = SDP_NewGenerator(); + if (generator == NULL) + return NULL; + + rv = _DescriptionAsString(generator, description); + if (SDP_FAILED(rv)) + { + SDP_DestroyGenerator(generator); + return NULL; + } + + generated_description = SDP_StrDup(SDP_GetGeneratedOutput(generator)); + + SDP_DestroyGenerator(generator); + + return generated_description; +} + + + + + +int SDP_OutputDescriptionsToFile( + SDP_Description * descriptions, + const char * filename) +{ + char *string; + FILE *file; + + SDP_AssertNotNull(descriptions); + SDP_AssertNotNull(filename); + + string = SDP_OutputDescriptionsToString(descriptions); + if (string == NULL) + return SDP_FAILURE; + + file = fopen(filename, "w"); + if (file == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_FILE_OPEN_FAILED, + "Couldn't open file to output descriptions to: %s.", + SDP_OS_ERROR_STRING + ); + SDP_Destroy(string); + return SDP_FAILURE; + } + + fwrite(string, 1, strlen(string), file); + + fclose(file); + SDP_Destroy(string); + + return SDP_SUCCESS; +} + + + + + +int SDP_OutputDescriptionToFile( + SDP_Description * description, + const char * filename) +{ + char *string; + FILE *file; + + SDP_AssertNotNull(description); + SDP_AssertNotNull(filename); + + string = SDP_OutputDescriptionToString(description); + if (string == NULL) + return SDP_FAILURE; + + file = fopen(filename, "w"); + if (file == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_FILE_OPEN_FAILED, + "Couldn't open file to output description to: %s.", + SDP_OS_ERROR_STRING + ); + SDP_Destroy(string); + return SDP_FAILURE; + } + + fwrite(string, 1, strlen(string), file); + + fclose(file); + SDP_Destroy(string); + + return SDP_SUCCESS; +} + + + + + +/* This adds formatted strings to the generator output buffer: */ +static int _Generate( + SDP_Generator * generator, + const char * format, + ... +); + +SDP_Generator *SDP_NewGenerator(void) +{ + SDP_Generator *generator = + (SDP_Generator *) SDP_Allocate(sizeof(SDP_Generator)); + if (generator == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to create a new SDP " + "generator: %s.", + SDP_OS_ERROR_STRING + ); + } + + memset(generator, 0, sizeof(SDP_Generator)); + + return generator; +} + + + + + +int SDP_GenProtocolVersionField( + SDP_Generator * generator, + int protocol_version) +{ + SDP_AssertNotNull(generator); + + return _Generate(generator, "v=%d\n", protocol_version); +} + + + + + +int SDP_GenOwnerField( + SDP_Generator * generator, + const char * username, + const char * session_id, + const char * session_version, + const char * network_type, + const char * address_type, + const char * address) +{ + SDP_AssertNotNull(generator); + + return _Generate( + generator, + "o=%s %s %s %s %s %s\n", + username ? username : "-", + STRINGIFY(session_id), + session_version ? session_version : "0", + STRINGIFY(network_type), + STRINGIFY(address_type), + STRINGIFY(address) + ); +} + + + + + +int SDP_GenFromOwner( + SDP_Generator * generator, + SDP_Owner * owner) +{ + SDP_AssertNotNull(generator); + SDP_AssertNotNull(owner); + + return SDP_GenOwnerField( + generator, + SDP_GetUsername(owner), + SDP_GetSessionID(owner), + SDP_GetSessionVersion(owner), + SDP_GetOwnerNetworkType(owner), + SDP_GetOwnerAddressType(owner), + SDP_GetOwnerAddress(owner) + ); +} + + + + + +int SDP_GenSessionNameField( + SDP_Generator * generator, + const char * session_name) +{ + SDP_AssertNotNull(generator); + + return _Generate(generator, "s=%s\n", STRINGIFY(session_name)); +} + + + + + +int SDP_GenInformationField( + SDP_Generator * generator, + const char * information) +{ + SDP_AssertNotNull(generator); + + return _Generate(generator, "i=%s\n", STRINGIFY(information)); +} + + + + + +int SDP_GenURIField( + SDP_Generator * generator, + const char * uri) +{ + SDP_AssertNotNull(generator); + + return _Generate(generator, "u=%s\n", STRINGIFY(uri)); +} + + + + + +int SDP_GenEmailContactField( + SDP_Generator * generator, + const char * address, + const char * name) +{ + SDP_AssertNotNull(generator); + + if (name) + return _Generate( + generator, "e=%s <%s>\n", name, STRINGIFY(address) + ); + else + return _Generate(generator, "e=%s\n", STRINGIFY(address)); +} + + + + + +int SDP_GenFromEmailContacts( + SDP_Generator * generator, + SDP_EmailContact * email_contacts) +{ + SDP_EmailContact *email_contact; + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(email_contacts); + + email_contact = email_contacts; + while (email_contact) + { + rv = SDP_GenFromEmailContact(generator, email_contact); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + email_contact = SDP_GetNextEmailContact(email_contact); + } + + return SDP_SUCCESS; +} + + + + + +int SDP_GenFromEmailContact( + SDP_Generator * generator, + SDP_EmailContact * email_contact) +{ + SDP_AssertNotNull(generator); + SDP_AssertNotNull(email_contact); + + return SDP_GenEmailContactField( + generator, + SDP_GetEmailAddress(email_contact), + SDP_GetEmailName(email_contact) + ); +} + + + + + + +int SDP_GenPhoneContactField( + SDP_Generator * generator, + const char * number, + const char * name) +{ + SDP_AssertNotNull(generator); + + if (name) + return _Generate( + generator, + "p=%s (%s)\n", + STRINGIFY(number), + name + ); + else + return _Generate(generator, "p=%s\n", STRINGIFY(number)); +} + + + + + +int SDP_GenFromPhoneContacts( + SDP_Generator * generator, + SDP_PhoneContact * phone_contacts) +{ + SDP_PhoneContact *phone_contact; + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(phone_contacts); + + phone_contact = phone_contacts; + while (phone_contact) + { + rv = SDP_GenFromPhoneContact(generator, phone_contact); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + phone_contact = SDP_GetNextPhoneContact(phone_contact); + } + + return SDP_SUCCESS; +} + + + + + +int SDP_GenFromPhoneContact( + SDP_Generator * generator, + SDP_PhoneContact * phone_contact) +{ + SDP_AssertNotNull(generator); + SDP_AssertNotNull(phone_contact); + + return SDP_GenPhoneContactField( + generator, + SDP_GetPhoneNumber(phone_contact), + SDP_GetPhoneName(phone_contact) + ); +} + + + + + +int SDP_GenConnectionField( + SDP_Generator * generator, + const char * network_type, + const char * address_type, + const char * address, + int ttl, + int total_addresses) +{ + SDP_AssertNotNull(generator); + + if (ttl && total_addresses) + return _Generate( + generator, + "c=%s %s %s/%d/%d\n", + STRINGIFY(network_type), + STRINGIFY(address_type), + STRINGIFY(address), + ttl, + total_addresses + ); + else if (ttl) + return _Generate( + generator, + "c=%s %s %s/%d\n", + STRINGIFY(network_type), + STRINGIFY(address_type), + STRINGIFY(address), + ttl + ); + else + return _Generate( + generator, + "c=%s %s %s\n", + STRINGIFY(network_type), + STRINGIFY(address_type), + STRINGIFY(address) + ); +} + + + + + +int SDP_GenFromConnection( + SDP_Generator * generator, + SDP_Connection * connection) +{ + SDP_AssertNotNull(generator); + SDP_AssertNotNull(connection); + + return SDP_GenConnectionField( + generator, + SDP_GetConnectionNetworkType(connection), + SDP_GetConnectionAddressType(connection), + SDP_GetConnectionAddress(connection), + SDP_GetConnectionTTL(connection), + SDP_GetTotalConnectionAddresses(connection) + ); +} + + + + + +int SDP_GenBandwidthField( + SDP_Generator * generator, + const char * modifier, + long value) +{ + SDP_AssertNotNull(generator); + + return _Generate( + generator, + "b=%s:%ld\n", + STRINGIFY(modifier), + value + ); +} + + + + + +int SDP_GenFromBandwidth( + SDP_Generator * generator, + SDP_Bandwidth * bandwidth) +{ + SDP_AssertNotNull(generator); + SDP_AssertNotNull(bandwidth); + + return SDP_GenBandwidthField( + generator, + SDP_GetBandwidthModifier(bandwidth), + SDP_GetBandwidthValue(bandwidth) + ); +} + + + + + +int SDP_GenSessionPlayTimeField( + SDP_Generator * generator, + time_t start_time, + time_t end_time) +{ + SDP_AssertNotNull(generator); + + return _Generate( + generator, + "t=%lu %lu\n", + OS_TIME_TO_NETWORK_TIME(start_time), + OS_TIME_TO_NETWORK_TIME(end_time) + ); +} + + + + + +int SDP_GenFromSessionPlayTimes( + SDP_Generator * generator, + SDP_SessionPlayTime * session_play_times) +{ + SDP_SessionPlayTime *session_play_time; + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(session_play_times); + + session_play_time = session_play_times; + while (session_play_time) + { + rv = SDP_GenFromSessionPlayTime( + generator, session_play_time + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + session_play_time = + SDP_GetNextSessionPlayTime(session_play_time); + } + + return SDP_SUCCESS; +} + + + + + +int SDP_GenFromSessionPlayTime( + SDP_Generator * generator, + SDP_SessionPlayTime * session_play_time) +{ + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(session_play_time); + + rv = SDP_GenSessionPlayTimeField( + generator, + SDP_GetStartTime(session_play_time), + SDP_GetEndTime(session_play_time) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + if (SDP_GetRepeatTimes(session_play_time)) + { + rv = SDP_GenFromRepeatTimes( + generator, + SDP_GetRepeatTimes(session_play_time) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + return SDP_SUCCESS; +} + + + + + +int SDP_GenRepeatTimeField( + SDP_Generator * generator, + const char * repeat_interval, + const char * active_duration, + const char * repeat_offsets) +{ + int rv; + + SDP_AssertNotNull(generator); + + rv = _Generate( + generator, + "r=%s %s", + STRINGIFY(repeat_interval), + STRINGIFY(active_duration) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + if (repeat_offsets && *repeat_offsets) + { + rv = _Generate(generator, " %s", repeat_offsets); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + rv = _Generate(generator, "\n"); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + return SDP_SUCCESS; +} + + + + + +int SDP_GenFromRepeatTimes( + SDP_Generator * generator, + SDP_RepeatTime * repeat_times) +{ + SDP_RepeatTime *repeat_time; + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(repeat_times); + + repeat_time = repeat_times; + while (repeat_time) + { + rv = SDP_GenFromRepeatTime(generator, repeat_time); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + repeat_time = SDP_GetNextRepeatTime(repeat_time); + } + + return SDP_SUCCESS; +} + + + + + +int SDP_GenFromRepeatTime( + SDP_Generator * generator, + SDP_RepeatTime * repeat_time) +{ + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(repeat_time); + + rv = _Generate( + generator, + "%lu %lu", + SDP_GetRepeatInterval(repeat_time), + SDP_GetActiveDuration(repeat_time) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + if (SDP_GetTotalRepeatOffsets(repeat_time)) + { + int total_offsets; + unsigned long *offsets; + int i; + + total_offsets = SDP_GetTotalRepeatOffsets(repeat_time); + offsets = SDP_GetRepeatOffsets(repeat_time); + for (i = 0; i < total_offsets; ++i) + { + rv = _Generate(generator, " %lu", offsets[i]); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + } + + return SDP_SUCCESS; +} + + + + + +int SDP_GenZoneAdjustmentsField( + SDP_Generator * generator, + int total_adjustments, + ...) +{ + int rv; + + rv = _Generate(generator, "z="); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + if (total_adjustments) + { + va_list zone_adjustments; + int i; + + va_start(zone_adjustments, total_adjustments); + for (i = 0; i < total_adjustments; ++i) + { + rv = _Generate( + generator, + " %lu %s", + OS_TIME_TO_NETWORK_TIME( + va_arg(zone_adjustments, long) + ), + va_arg(zone_adjustments, char *) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + va_end(zone_adjustments); + } + + rv = _Generate(generator, "\n"); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + return SDP_SUCCESS; +} + + + + + +int SDP_GenFromZoneAdjustments( + SDP_Generator * generator, + SDP_ZoneAdjustment * zone_adjustments) +{ + SDP_ZoneAdjustment *zone_adjustment; + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(zone_adjustments); + + rv = _Generate(generator, "z="); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + zone_adjustment = zone_adjustments; + while (zone_adjustment) + { + rv = _Generate( + generator, + "%lu %ld", + (unsigned long) SDP_GetZoneAdjustmentTime( + zone_adjustment + ), + SDP_GetZoneAdjustmentOffset(zone_adjustment) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + zone_adjustment = SDP_GetNextZoneAdjustment(zone_adjustment); + + /* + * Add the space to separate this adjustment from the next one: + */ + if (zone_adjustment) + { + rv = _Generate(generator, " "); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + } + + return SDP_SUCCESS; +} + + + + + +int SDP_GenEncryptionField( + SDP_Generator * generator, + const char * method, + const char * key) +{ + SDP_AssertNotNull(generator); + + if (key) + return _Generate( + generator, "e=%s:%s\n", STRINGIFY(method), key + ); + else + return _Generate(generator, "e=%s\n", STRINGIFY(method)); +} + + + + + +int SDP_GenFromEncryption( + SDP_Generator * generator, + SDP_Encryption * encryption) +{ + SDP_AssertNotNull(generator); + SDP_AssertNotNull(encryption); + + return SDP_GenEncryptionField( + generator, + SDP_GetEncryptionMethod(encryption), + SDP_GetEncryptionKey(encryption) + ); +} + + + + + +int SDP_GenAttributeField( + SDP_Generator * generator, + const char * name, + const char * value) +{ + SDP_AssertNotNull(generator); + + if (value) + return _Generate( + generator, "a=%s:%s\n", STRINGIFY(name), value + ); + else + return _Generate(generator, "a=%s\n", STRINGIFY(name)); +} + + + + + +int SDP_GenFromAttributes( + SDP_Generator * generator, + SDP_Attribute * attributes) +{ + SDP_Attribute *attribute; + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(attributes); + + attribute = attributes; + while (attribute) + { + rv = SDP_GenFromAttribute(generator, attribute); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + attribute = SDP_GetNextAttribute(attribute); + } + + return SDP_SUCCESS; +} + + + + + +int SDP_GenFromAttribute( + SDP_Generator * generator, + SDP_Attribute * attribute) +{ + SDP_AssertNotNull(generator); + SDP_AssertNotNull(attribute); + + return SDP_GenAttributeField( + generator, + SDP_GetAttributeName(attribute), + SDP_GetAttributeValue(attribute) + ); +} + + + + + +int SDP_GenMediaDescriptionField( + SDP_Generator * generator, + const char * media_type, + const char * port, + const char * transport_protocol, + const char * formats) +{ + if (formats) + return _Generate( + generator, + "m=%s %s %s %s\n", + STRINGIFY(media_type), + STRINGIFY(port), + STRINGIFY(transport_protocol), + formats + ); + else + return _Generate( + generator, + "m=%s %s %s\n", + STRINGIFY(media_type), + STRINGIFY(port), + STRINGIFY(transport_protocol) + ); +} + + + + + +int SDP_GenFromMediaDescriptions( + SDP_Generator * generator, + SDP_MediaDescription * media_descriptions) +{ + SDP_MediaDescription *media_description; + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(media_descriptions); + + media_description = media_descriptions; + while (media_description) + { + rv = SDP_GenFromMediaDescription(generator, media_description); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + media_description = + SDP_GetNextMediaDescription(media_description); + } + + return SDP_SUCCESS; +} + + + + + +int SDP_GenFromMediaDescription( + SDP_Generator * generator, + SDP_MediaDescription * media_description) +{ + char port_string[64]; + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(media_description); + + if (SDP_GetMediaPort(media_description) + && SDP_GetTotalMediaPorts(media_description)) + snprintf( + port_string, + sizeof(port_string), + "%d/%d", + SDP_GetMediaPort(media_description), + SDP_GetTotalMediaPorts(media_description) + ); + else + snprintf( + port_string, + sizeof(port_string), + "%d", + SDP_GetMediaPort(media_description) + ); + + rv = SDP_GenMediaDescriptionField( + generator, + SDP_GetMediaType(media_description), + port_string, + SDP_GetMediaTransportProtocol(media_description), + SDP_GetMediaFormats(media_description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + if (SDP_GetMediaInformation(media_description)) + { + rv = SDP_GenInformationField( + generator, SDP_GetMediaInformation(media_description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetMediaConnection(media_description)) + { + rv = SDP_GenFromConnection( + generator, SDP_GetMediaConnection(media_description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetMediaBandwidth(media_description)) + { + rv = SDP_GenFromBandwidth( + generator, SDP_GetMediaBandwidth(media_description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetMediaAttributes(media_description)) + { + rv = SDP_GenFromAttributes( + generator, SDP_GetMediaAttributes(media_description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + return SDP_SUCCESS; +} + + + + + +char *SDP_GetGeneratedOutput(SDP_Generator *generator) +{ + SDP_AssertNotNull(generator); + + return SDP_GetStrBuffer(generator->output_buffer); +} + + + + + +int SDP_SaveGeneratedOutput( + SDP_Generator * generator, + const char * filename) +{ + FILE *file; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(filename); + + file = fopen(filename, "w"); + if (file == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_FILE_OPEN_FAILED, + "Couldn't open file \"%s\" to save the generated SDP " + "description: %s.", + filename, + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + fwrite( + SDP_GetStrBuffer(generator->output_buffer), + 1, + SDP_GetStrLength(generator->output_buffer), + file + ); + + fclose(file); + + return SDP_SUCCESS; +} + + + + + +void SDP_DestroyGenerator(SDP_Generator *generator) +{ + SDP_DestroyStrBuffer(&generator->output_buffer); + + SDP_Destroy(generator); +} + + + + + +static unsigned long _ApproximateLength( + const char * format, + va_list args +); + +/******************************************************************************* + * + * Name + * _Generate(generator, format, ...) + * + * Purpose + * This function "generates"; it adds a formatted string to to the + * SDP_Generator struct's output buffer, allocating memory as + * needed. + * + * It returns true if it successfully adds the formatted string to + * the buffer, false otherwise. + * + * Parameters + * generator - A pointer an SDP_Generator struct. + * format - A printf() format string. + * ... - The variables to fill the string with. + * + */ + +static int _Generate( + SDP_Generator * generator, + const char * format, + ...) +{ + va_list args; + size_t bytes_needed; + int rv; + + SDP_AssertNotNull(generator); + SDP_AssertNotNull(format); + + /* + * Figure out how many bytes we're gonna need for this formatted + * string: + */ + va_start(args, format); + bytes_needed = _ApproximateLength(format, args); + va_end(args); + + /* Now add the formatted string to the buffer: */ + va_start(args, format); + rv = SDP_CatToStrUsingFormat( + &generator->output_buffer, bytes_needed, format, args + ); + va_end(args); + + if (SDP_FAILED(rv)) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to generate SDP " + "description: %s.", + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _ApproximateLength(format, args) + * + * Purpose + * Takes a format string and a va_list of arguments to fill it + * with. It tries to find out how many bytes would be needed for + * a snprintf() with that format and those arguments to succeed + * without cutting off the resulting string, and returns that + * value. It's an approximation, and a liberal one at that, so it + * *shouldn't* return a value too small, but it *probably* will + * return a value too big. + * + * C99 says that if snprintf() truncates the string, it returns + * the number of bytes that *would* have been written to if enough + * space was available, but sadly, snprintf() implementations + * differ wildly in what they return, where snprintf() exist at + * all, e.g.: + * + * "The glibc implementation of the functions snprintf and + * vsnprintf . . . . [u]ntil glibc 2.0.6 . . . would return -1 + * when the output was truncated." - man 3 snprintf + * + * So this function is needed. Otherwise we need to implement + * snprintf() on our own or try to port it, which is overkill. + * + * Parameters + * format - A snprintf() format string. + * args - A va_list. + * + */ + +#define NO_MODIFIERS 0 +#define IS_LONG 1 +#define IS_SHORT 2 + +static unsigned long _ApproximateLength( + const char * format, + va_list args) +{ + unsigned long length = 0; + + while (*format) + { + int modifiers = NO_MODIFIERS; + + if (*format != '%') + { + ++format; + ++length; + continue; + } + + if (strncmp(format, "%%", 2) == 0) + { + format += 2; + length += 1; + continue; + } + + ++format; + if (*format == '\0') + { + ++length; + break; + } + + /* Check for short and long modifiers: */ + if (*format == 'h' || *format == 'H') + { + modifiers |= IS_SHORT; + ++format; + } + else if (*format == 'l' || *format == 'L') + { + modifiers |= IS_LONG; + ++format; + } + + switch (*format) + { + case 'c': + case 'C': + ++length; + ++format; + va_arg(args, int); + continue; + case 's': + case 'S': + length += strlen(va_arg(args, char *)); + ++format; + continue; + case 'u': + case 'U': + case 'd': + case 'D': + case 'i': + case 'I': + /* + * A cop-out. This is far, far, more than + * enough room, even for a 64 bit int: + */ + length += 24; + ++format; + va_arg(args, int); + continue; + default: + ++length; + ++format; + va_arg(args, int); + continue; + } + } + + ++length; + + return length; +} + + + + + +/******************************************************************************* + * + * Name + * _DescriptionAsString(generator, description) + * + * Purpose + * This function "generates"; it adds a formatted string to to the + * SDP_Generator struct's output buffer, allocating memory as + * needed. + * + * It returns true if it successfully adds the formatted string to + * the buffer, false otherwise. + * + * Parameters + * generator - A pointer to the SDP_Generator struct to generate + * to. + * description - A pointer to the SDP_Description struct to + * generate from. + * + */ + +static int _DescriptionAsString( + SDP_Generator * generator, + SDP_Description * description) +{ + int rv; + + rv = SDP_GenProtocolVersionField( + generator, SDP_GetProtocolVersion(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + if (SDP_GetOwner(description)) + { + rv = SDP_GenFromOwner( + generator, SDP_GetOwner(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetSessionName(description)) + { + rv = SDP_GenSessionNameField( + generator, SDP_GetSessionName(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetSessionInformation(description)) + { + rv = SDP_GenInformationField( + generator, + SDP_GetSessionInformation(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetURI(description)) + { + rv = SDP_GenURIField(generator, SDP_GetURI(description)); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetEmailContacts(description)) + { + rv = SDP_GenFromEmailContacts( + generator, SDP_GetEmailContacts(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetPhoneContacts(description)) + { + rv = SDP_GenFromPhoneContacts( + generator, SDP_GetPhoneContacts(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetConnection(description)) + { + rv = SDP_GenFromConnection( + generator, SDP_GetConnection(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetBandwidth(description)) + { + rv = SDP_GenFromBandwidth( + generator, SDP_GetBandwidth(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetSessionPlayTimes(description)) + { + rv = SDP_GenFromSessionPlayTimes( + generator, SDP_GetSessionPlayTimes(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetZoneAdjustments(description)) + { + rv = SDP_GenFromZoneAdjustments( + generator, SDP_GetZoneAdjustments(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetAttributes(description)) + { + rv = SDP_GenFromAttributes( + generator, SDP_GetAttributes(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + if (SDP_GetMediaDescriptions(description)) + { + rv = SDP_GenFromMediaDescriptions( + generator, SDP_GetMediaDescriptions(description) + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + return SDP_SUCCESS; +} diff --git a/src/sdp_lib/src/SDP_Generator.h b/src/sdp_lib/src/SDP_Generator.h new file mode 100644 index 0000000..a63e0bd --- /dev/null +++ b/src/sdp_lib/src/SDP_Generator.h @@ -0,0 +1,219 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SDP_GENERATOR_INCLUDED +#define SDP_GENERATOR_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "SDP_Description.h" +#include "SDP_Error.h" +#include "SDP_LinkedList.h" +#include "SDP_Str.h" +#include "SDP_Utility.h" + + + +typedef struct { + /* + * A string struct containing a pointer to a malloc()'d buffer to store + * the SDP description as we generate it: + */ + SDP_Str output_buffer; +} SDP_Generator; + + + +extern char *SDP_OutputDescriptionsToString(SDP_Description *descriptions); +extern char *SDP_OutputDescriptionToString(SDP_Description *description); +extern int SDP_OutputDescriptionsToFile( + SDP_Description * descriptions, + const char * filename +); +extern int SDP_OutputDescriptionToFile( + SDP_Description * description, + const char * filename +); + +extern SDP_Generator *SDP_NewGenerator(void); + +extern int SDP_GenProtocolVersionField( + SDP_Generator * generator, + int protocol_version +); +extern int SDP_GenOwnerField( + SDP_Generator * generator, + const char * username, + const char * session_id, + const char * session_version, + const char * network_type, + const char * address_type, + const char * address +); +extern int SDP_GenFromOwner( + SDP_Generator * generator, + SDP_Owner * owner +); +extern int SDP_GenSessionNameField( + SDP_Generator * generator, + const char * session_name +); +extern int SDP_GenInformationField( + SDP_Generator * generator, + const char * information +); +extern int SDP_GenURIField( + SDP_Generator * generator, + const char * uri +); +extern int SDP_GenEmailContactField( + SDP_Generator * generator, + const char * address, + const char * name +); +extern int SDP_GenFromEmailContacts( + SDP_Generator * generator, + SDP_EmailContact * email_contacts +); +extern int SDP_GenFromEmailContact( + SDP_Generator * generator, + SDP_EmailContact * email_contact +); +extern int SDP_GenPhoneContactField( + SDP_Generator * generator, + const char * number, + const char * name +); +extern int SDP_GenFromPhoneContacts( + SDP_Generator * generator, + SDP_PhoneContact * phone_contacts +); +extern int SDP_GenFromPhoneContact( + SDP_Generator * generator, + SDP_PhoneContact * phone_contact +); +extern int SDP_GenConnectionField( + SDP_Generator * generator, + const char * network_type, + const char * address_type, + const char * address, + int ttl, + int total_addresses +); +extern int SDP_GenFromConnection( + SDP_Generator * generator, + SDP_Connection * connection +); +extern int SDP_GenBandwidthField( + SDP_Generator * generator, + const char * modifier, + long value +); +extern int SDP_GenFromBandwidth( + SDP_Generator * generator, + SDP_Bandwidth * bandwidth +); +extern int SDP_GenSessionPlayTimeField( + SDP_Generator * generator, + time_t start_time, + time_t end_time +); +extern int SDP_GenFromSessionPlayTimes( + SDP_Generator * generator, + SDP_SessionPlayTime * session_play_times +); +extern int SDP_GenFromSessionPlayTime( + SDP_Generator * generator, + SDP_SessionPlayTime * session_play_time +); +extern int SDP_GenRepeatTimeField( + SDP_Generator * generator, + const char * repeat_interval, + const char * active_duration, + const char * repeat_offsets +); +extern int SDP_GenFromRepeatTimes( + SDP_Generator * generator, + SDP_RepeatTime * repeat_times +); +extern int SDP_GenFromRepeatTime( + SDP_Generator * generator, + SDP_RepeatTime * repeat_time +); +extern int SDP_GenZoneAdjustmentsField( + SDP_Generator * generator, + int total_adjustments, + ... +); +extern int SDP_GenFromZoneAdjustments( + SDP_Generator * generator, + SDP_ZoneAdjustment * zone_adjustments +); +extern int SDP_GenEncryptionField( + SDP_Generator * generator, + const char * method, + const char * key +); +extern int SDP_GenFromEncryption( + SDP_Generator * generator, + SDP_Encryption * encryption +); +extern int SDP_GenAttributeField( + SDP_Generator * generator, + const char * name, + const char * value +); +extern int SDP_GenFromAttributes( + SDP_Generator * generator, + SDP_Attribute * attributes +); +extern int SDP_GenFromAttribute( + SDP_Generator * generator, + SDP_Attribute * attribute +); +extern int SDP_GenMediaDescriptionField( + SDP_Generator * generator, + const char * media_type, + const char * port, + const char * transport_protocol, + const char * formats +); +extern int SDP_GenFromMediaDescriptions( + SDP_Generator * generator, + SDP_MediaDescription * media_descriptions +); +extern int SDP_GenFromMediaDescription( + SDP_Generator * generator, + SDP_MediaDescription * media_description +); + +extern char *SDP_GetGeneratedOutput(SDP_Generator *generator); +extern int SDP_SaveGeneratedOutput( + SDP_Generator * generator, + const char * filename +); + +extern void SDP_DestroyGenerator(SDP_Generator *generator); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdp_lib/src/SDP_LinkedList.h b/src/sdp_lib/src/SDP_LinkedList.h new file mode 100644 index 0000000..b9309eb --- /dev/null +++ b/src/sdp_lib/src/SDP_LinkedList.h @@ -0,0 +1,138 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SDP_LINKEDLIST_INCLUDED +#define SDP_LINKEDLIST_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SDP_Utility.h" + + + + + +typedef struct { + /* Pointer to the first element in the linked list: */ + void *elements; + + /* The total number of elements in the linked list: */ + int total_elements; + + /* A pointer to the last element in the linked list: */ + void *last_element; +} SDP_LinkedList; + + + +/* These macros are used as accessors for STD_LinkedList structs: */ +#define SDP_GetListElements(_list_) ((_list_).elements) +#define SDP_GetTotalElements(_list_) ((_list_).total_elements) +#define SDP_GetLastElement(_list_) ((_list_).last_element) + +/* + * Generic next/previous linked list macros for structs that are chained + * together to form lists: + */ +#define SDP_GetNext(_object_) \ + ((_object_) ? (_object_)->next : NULL) +#define SDP_GetPrevious(_object_) \ + ((_object_) ? (_object_)->previous : NULL) + +#define SDP_SetNext(_object_, _next_) \ + ((_object_) ? (_object_)->next = _next_ : NULL) +#define SDP_SetPrevious(_object_, _previous_) \ + ((_object_) ? (_object_)->previous = _previous_ : NULL) + +/* + * This macro adds the struct "_new_object_" of type "_type_" to the + * SDP_LinkedList struct "_list_": + */ +#define SDP_LINK_INTO_LIST(_list_, _new_object_, _type_) \ + do { \ + if ((_list_).elements) \ + { \ + _type_ *last_element = \ + (_type_ *) (_list_).last_element; \ + \ + SDP_SetNext(last_element, _new_object_); \ + SDP_SetPrevious(_new_object_, last_element); \ + } \ + else \ + { \ + (_list_).elements = _new_object_; \ + } \ + \ + (_list_).last_element = _new_object_; \ + ++(_list_).total_elements; \ + } while (0) + +/* + * This macro removes the struct "_object_" of type "_type_" from the + * SDP_LinkedList struct "_list_": + */ +#define SDP_UNLINK_FROM_LIST(_list_, _object_, _type_) \ + do { \ + if ((_object_)->next && (_object_)->previous) \ + { \ + (_object_)->next->previous = (_object_)->previous; \ + (_object_)->previous->next = (_object_)->next; \ + } \ + else if ((_object_)->next) \ + { \ + (_object_)->next->previous = NULL; \ + (_list_).elements = (_object_)->next; \ + } \ + else if ((_object_)->previous) \ + { \ + (_object_)->previous->next = NULL; \ + (_list_).last_element = (_object_)->previous; \ + } \ + \ + --(_list_).total_elements; \ + } while (0) + +/* + * This macro destorys each struct of type "_type_" from the SDP_LinkedList + * struct "_list_" using the destroy function "_function_": + */ +#define SDP_DESTROY_LIST(_list_, _type_, _function_) \ + do { \ + _type_ *object = (_list_).elements; \ + \ + while (object) \ + { \ + _type_ *object_to_destroy = object; \ + \ + object = object->next; \ + \ + _function_(object_to_destroy); \ + } \ + \ + (_list_).elements = NULL; \ + (_list_).total_elements = 0; \ + (_list_).last_element = NULL; \ + } while (0) + + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdp_lib/src/SDP_Parser.c b/src/sdp_lib/src/SDP_Parser.c new file mode 100644 index 0000000..aa0b1dc --- /dev/null +++ b/src/sdp_lib/src/SDP_Parser.c @@ -0,0 +1,2322 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + * This file contains routines that parse individual SDP fields and fill + * SDP_Description structs. It uses the event stream parser and defines its own + * custom event handlers to do the additional parsing of each field. It uses + * the SDP generator to output the description. + * + *------------------------------------------------------------------------------ + * + * See SinisterSdpParser.html for documentation. + * + ******************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include "SDP_Error.h" +#include "SDP_EventStreamParser.h" +#include "SDP_Generator.h" +#include "SDP_LinkedList.h" +#include "SDP_Parser.h" +#include "SDP_Str.h" +#include "SDP_Description.h" +#include "SDP_Utility.h" + +/* + * This is used to test an error string supplied as the first argument to + * _CheckForMissingField() after calling _CheckForMissingField(): + */ +#define ARE_REQUIRED_FIELDS_MISSING(_string_) \ + (((_string_) && *(_string_)) ? 1: 0) + +/* + * This converts string containing a Network Time Protocol timestamp to + * a time_t: + */ +#define NTP_DIFFERENCE 2208988800UL +#define NETWORK_TIME_TO_OS_TIME(_ntp_time_value_) \ + (((_ntp_time_value_) >= NTP_DIFFERENCE) \ + ? ((time_t) ((_ntp_time_value_) - NTP_DIFFERENCE)) \ + : ((time_t) (_ntp_time_value_))) + + + + + + + +/* This struct is used to build up the SDP_Description structs: */ +typedef struct { + /* A pointer to the current event stream parser struct: */ + SDP_Parser *parser; + + /* + * We use our own custom handlers to build the descriptions, but before + * resgistering them, we save pointers to the user's event stream + * handlers and their user data, then when we're done, we set things + * back to the way they were: + */ + SDP_StartHandler saved_start_handler; + SDP_StartDescriptionHandler saved_start_description_handler; + SDP_FieldHandler saved_field_handler; + SDP_EndDescriptionHandler saved_end_description_handler; + SDP_EndHandler saved_end_handler; + void * saved_user_data; + + /* + * A pointer to the place to store the pointer to the resulting session + * description structs: + */ + SDP_Description **descriptions_destination; + + /* The linked list of session descriptions we're going to build: */ + SDP_LinkedList descriptions; + + /* The current state of the description builder: */ + enum { + BUILDING_DESCRIPTION_STRUCTS, + BUILDING_SESSION_TIME_STRUCTS, + BUILDING_MEDIA_DESCRIPTION_STRUCTS + } state; + + /* + * If we're parsing time fields at the moment, then this will contain + * the current time struct we're filling: + */ + SDP_SessionPlayTime *current_session_play_time; + + /* + * If we're parsing media description fields at the moment, then this + * will contain a pointer to the current media description struct we're + * filling: + */ + SDP_MediaDescription *current_media_description; +} SDP_DescriptionBuilder; + + + + + +/* Registers our handlers with the event stream parser to build the structs: */ +static int _RegisterCustomHandlers( + SDP_Parser * parser, + SDP_Description ** descriptions_destination +); + +/* The custom handlers used to build the SDP_Description description: */ +static int _CustomStartDescriptionHandler( + SDP_Parser * parser, + int current_description, + void * user_data +); +static int _CustomFieldHandler( + SDP_Parser * parser, + char field_type, + const char * field_value, + void * user_data +); +static void _CustomEndHandler( + SDP_Parser * parser, + int result, + void * user_data +); + +/* + * This array stores pointers to functions to handle each specific type of SDP + * field: + */ +static int (*_field_parsers_table[256])( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value +); + +/* Has the array been initialized yet? */ +static int _field_parsers_table_initialized = 0; + +/* This function initializes the function pointer table to parse each field: */ +static void _InitializeFieldParsersTable(void); + + + + + +SDP_Description *SDP_Parse( + SDP_Parser * parser, + const char * string) +{ + SDP_Description *descriptions; + int rv; + + SDP_AssertNotNull(parser); + SDP_AssertNotNull(string); + + rv = _RegisterCustomHandlers(parser, &descriptions); + if (SDP_FAILED(rv)) + return NULL; + + SDP_EventStreamParse(parser, string); + + return descriptions; +} + + + + + +SDP_Description *SDP_ParseFile( + SDP_Parser * parser, + const char * filename) +{ + SDP_Description *descriptions; + int rv; + + SDP_AssertNotNull(parser); + SDP_AssertNotNull(filename); + + rv = _RegisterCustomHandlers(parser, &descriptions); + if (SDP_FAILED(rv)) + return NULL; + + SDP_EventStreamParseFile(parser, filename); + + return descriptions; +} + + + + + +/******************************************************************************* + * + * Name + * _RegisterCustomHandlers(parser, descriptions_destination) + * + * Purpose + * This function registers handlers with the event stream parser + * that extract values from each field and create and fill + * SDP_Description structs with them. + * + * It creates a new SDP_DescriptionBuilder struct, saves away the + * user's event handlers and user data in it, then overwrites them + * in the parser struct with its own custom handlers that build up + * the structs, and sets the description builder struct as the user + * data so it gets passed to those registered handlers. + * + * It returns true if it succeeds, false if it fails (if it + * couldn't allocate memory for the SDP_DescriptionBuilder struct). + * + * Parameters + * parser - A pointer to a parser struct. + * descriptions_destination - A pointer to an SDP_Description + * pointer that will end up pointing + * to the first struct in the list if + * parsing was successful or NULL if it + * was unsuccessful. + * + */ + +static int _RegisterCustomHandlers( + SDP_Parser * parser, + SDP_Description ** descriptions_destination) +{ + SDP_DescriptionBuilder *description_builder = + (SDP_DescriptionBuilder *) SDP_Allocate( + sizeof(SDP_DescriptionBuilder) + ); + if (description_builder == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory for the SDP description " + "builder: %s.", + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + memset(description_builder, 0, sizeof(SDP_DescriptionBuilder)); + + description_builder->parser = parser; + + description_builder->descriptions_destination = + descriptions_destination; + + /* Save the user's event handlers... */ + description_builder->saved_start_handler = + SDP_GetStartHandler(parser); + description_builder->saved_start_description_handler = + SDP_GetStartDescriptionHandler(parser); + description_builder->saved_field_handler = + SDP_GetFieldHandler(parser); + description_builder->saved_end_description_handler = + SDP_GetEndDescriptionHandler(parser); + description_builder->saved_end_handler = + SDP_GetEndHandler(parser); + + /* ...and their user data: */ + description_builder->saved_user_data = SDP_GetUserData(parser); + + /* ...so we can overwrite them: */ + SDP_SetStartHandler(parser, NULL); + SDP_SetStartDescriptionHandler(parser, _CustomStartDescriptionHandler); + SDP_SetFieldHandler(parser, _CustomFieldHandler); + SDP_SetEndDescriptionHandler(parser, NULL); + SDP_SetEndHandler(parser, _CustomEndHandler); + + /* + * We pass our builder struct to each of the registered hadlers as user + * data: + */ + SDP_SetUserData(parser, description_builder); + + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _CustomStartDescriptionHandler( + * parser, current_description_number, user_data + * ); + * + * Purpose + * This function is registered by _RegisterCustomHandlers() as the + * start-of-description handler. It creates a new description + * struct to handle the description, and links it into the linked + * list of description structs. + * + * It returns true if it can create the struct, false if it can't. + * + * Parameters + * Same as all other start-of-description handlers. + * + */ + +static int _CustomStartDescriptionHandler( + SDP_Parser * parser, + int current_description_number, + void * user_data) +{ + SDP_DescriptionBuilder *description_builder; + SDP_Description *new_description; + + /* + * Allocate the new description struct and link it into the + * descriptions list: + */ + description_builder = (SDP_DescriptionBuilder *) user_data; + new_description = SDP_NewDescription(); + if (new_description == NULL) + return SDP_FAILURE; + + SDP_LINK_INTO_LIST( + description_builder->descriptions, + new_description, + SDP_Description + ); + + /* Set or reset the builder state: */ + description_builder->state = BUILDING_DESCRIPTION_STRUCTS; + + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _CustomFieldHandler(parser, field_type, field_value, user_data); + * + * Purpose + * This function is registered by _RegisterCustomHandlers() as the + * field handler. If it recognizes the field, it will invoke a + * function to parse it and store its values in the current + * SDP_Description struct being filled. + * + * It returns true if it parses the field successfully, false if + * it can't. + * + * Parameters + * Same as all field handlers. + * + */ + +static int _CustomFieldHandler( + SDP_Parser * parser, + char field_type, + const char * field_value, + void * user_data) +{ + SDP_DescriptionBuilder *description_builder; + int type_char; + + /* + * Probably isn't needed, as the event stream parser makes sure this + * is an unsigned char, but it can't hurt: + */ + type_char = field_type; + SDP_Assert(type_char > 0 && type_char < 255); + + /* Get our passed-around builder struct: */ + description_builder = (SDP_DescriptionBuilder *) user_data; + + /* + * Initialize the field parser function pointer table if we haven't + * done so yet: + */ + _InitializeFieldParsersTable(); + + /* + * Now invoke the proper handler for this specific type of field + * (the casts are just to shut GCC up; field_type has already been + * checked to make sure it's in range (not negative, not greater than + * 255): */ + if (_field_parsers_table[(unsigned char) field_type]) + return (*_field_parsers_table[(unsigned char) field_type])( + description_builder->parser, + description_builder, + SDP_GetLastElement(description_builder->descriptions), + field_value + ); + else + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _CustomEndHandler(parser, result, user_data); + * + * Purpose + * This function is registered by _RegisterCustomHandlers() as the + * end handler. It is invoked when parsing stops, and is tasked + * with unregistering the custom handlers and reregistering the + * user's handlers and user data that were saved away in the + * SDP_DescriptionBuilder struct. + * + * If parsing was successful, then it stores a pointer to the + * first SDP_Description struct in the linked list to the place + * specified by the second argument to _RegisterCustomHandlers(), + * otherwise, it stores a NULL pointer there instead. + * + * Parameters + * Same as all other end handlers. + * + */ + +static void _CustomEndHandler( + SDP_Parser * parser, + int result, + void * user_data) +{ + SDP_DescriptionBuilder *description_builder = + (SDP_DescriptionBuilder *) user_data; + + /* Overwrite our handlers with the user's: */ + SDP_SetStartHandler( + parser, description_builder->saved_start_handler + ); + SDP_SetStartDescriptionHandler( + parser, description_builder->saved_start_description_handler + ); + SDP_SetFieldHandler( + parser, description_builder->saved_field_handler + ); + SDP_SetEndDescriptionHandler( + parser, description_builder->saved_end_description_handler + ); + SDP_SetEndHandler( + parser, description_builder->saved_end_handler + ); + + /* ...and reset their user data: */ + SDP_SetUserData(parser, description_builder->saved_user_data); + + /* + * If we successfully parsed parsed the input and built up the + * descriptions, then we pass on a pointer to them. Otherwise, if + * parsing failed or something else bad happened (like if we ran out of + * memory), then we destory any malformed description and pass on a + * NULL pointer: + */ + if (SDP_SUCCEEDED(result)) + { + *(description_builder->descriptions_destination) = + SDP_GetListElements(description_builder->descriptions); + } + else + { + *(description_builder->descriptions_destination) = NULL; + SDP_DestroyDescriptions( + SDP_GetListElements(description_builder->descriptions) + ); + } + + SDP_Destroy(description_builder); +} + + + + + +/******************************************************************************* + * + * These functions handle specific SDP fields. They're called by the + * description builder's custom field handler where appropriate. + * + ******************************************************************************/ + +/* + * This is used by both _ParseEmailContactField() and + * _ParsePhoneContactField(), as "e" and "p" fields both share more or less the + * same format: + */ +#define ERR_MISSING_REQUIRED_FIELD 1 +#define ERR_MISSING_ANGLE_BRACKET_TERMINATOR 2 +#define ERR_MISSING_PARENTHESIS_TERMINATOR 3 + +static int _ParseContactField( + char * field_to_parse, + char ** required_value, + char ** optional_value, + int * error +); + +/* + * This is used to check if a required subfield is missing, and if it is, + * concatenate its name to a string containing the names of all other missing + * subfields separated by commas: + */ +static int _CheckForMissingField( + char * missing_fields, + const char * field, + const char * field_name +); + +/* + * This is used to convert a repeat time offset or zone adjustment offset from + * the "\d+[smhd]" format to a number of seconds: + */ +static int _GetOffsetInSeconds( + const char * string, + long * offset_in_seconds, + char * error_string, + size_t error_string_size +); + +/******************************************************************************* + * + * Name + * _ParseProtocolVersionField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * This function tries to extract a protocol version number from + * a "v" field and store it in the description struct. + * + * It returns true if it parses the field successfully, false + * otherwise. + * + */ + +static int _ParseProtocolVersionField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + int protocol_version = strtol(field_value, (char **) NULL, 10); + + if (protocol_version == 0 + && (SDP_OS_ERROR_CODE == EINVAL + || SDP_OS_ERROR_CODE == ERANGE)) + { + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_V_FIELD, + "Line %d contains a malformed \"v\" %s and could not " + "be parsed: %s", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('v'), + SDP_OS_ERROR_STRING + ); + } + + SDP_SetProtocolVersion(description, protocol_version); + + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseOwnerField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * This function tries to extract a the username, session ID, + * session version, network type, address type, and address from + * an "o" field and store them in the current description struct. + * + * It returns true if it parses the field successfully, false + * otherwise. + * + */ + +static int _ParseOwnerField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* Used to copy and traverse the "o" field value: */ + char *copy_of_field; + char *c; + + /* Pointers to each substring in the copy of the "o" field: */ + char *username; + char *session_id; + char *session_version; + char *network_type; + char *address_type; + char *address; + + /* + * This stores the name of each missing subfield for the error message + * we need to generate if the field is malformed: + */ + char missing_fields[128] = ""; + + int rv; + + + + /* Get a copy of the field to work with: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"o\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('o'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + + + /* Each of these subfields is required: */ + c = copy_of_field; + username = SDP_StrSep(&c, " "); + session_id = SDP_StrSep(&c, " "); + session_version = SDP_StrSep(&c, " "); + network_type = SDP_StrSep(&c, " "); + address_type = SDP_StrSep(&c, " "); + address = SDP_StrSep(&c, " "); + _CheckForMissingField(missing_fields, username, "username field"); + _CheckForMissingField(missing_fields, session_id, "session ID field"); + _CheckForMissingField( + missing_fields, session_version, "session version field" + ); + _CheckForMissingField(missing_fields, network_type, "network type"); + _CheckForMissingField(missing_fields, address_type, "address type"); + _CheckForMissingField(missing_fields, address, "address field"); + + if (ARE_REQUIRED_FIELDS_MISSING(missing_fields)) + { + rv = SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_O_FIELD, + "Line %d contains a malformed \"o\" %s and could not " + "be parsed. It is missing the following required " + "subfields: %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('o'), + missing_fields + ); + SDP_Destroy(copy_of_field); + + return rv; + } + + + + /* Set the internal SDP_Owner struct: */ + rv = SDP_SetOwner( + description, + username, + session_id, + session_version, + network_type, + address_type, + address + ); + + SDP_Destroy(copy_of_field); + + return rv; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseSessionNameField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Copies an "s" field and sets it to be the session name in the + * SDP_Description struct being built. + * + * It returns true if it can copy the field, false otherwise. + * + */ + +static int _ParseSessionNameField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + return SDP_SetSessionName(description, field_value); +} + + + + + +/******************************************************************************* + * + * Name + * _ParseInformationField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Copies "i" field value to be either the session information or + * media information depending on what fields have already been + * parsed and what struct is currently being built. + * + * It returns true if it can copy the field, false otherwise. + * + */ + +static int _ParseInformationField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + if (description_builder->state == BUILDING_MEDIA_DESCRIPTION_STRUCTS) + return SDP_SetMediaInformation( + description_builder->current_media_description, + field_value + ); + else + return SDP_SetSessionInformation(description, field_value); +} + + + + + +/******************************************************************************* + * + * Name + * _ParseSessionNameField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Copies a "u" field and sets it to be the URI of the session in + * the SDP_Description struct currently being built. + * + * It returns true if it can copy the field, false otherwise. + * + */ + +static int _ParseURIField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + return SDP_SetURI(description, field_value); +} + + + + + +/******************************************************************************* + * + * Name + * _ParseEmailContactField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse an "e" field and extract the email address and + * optional name of the person who can be reached at that address, + * and then creates an SDP_EmailContact struct with those values + * and adds it to the linked list of SDP_EmailContact structs in + * the SDP_Description struct currently being built. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParseEmailContactField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* String used to chop up the "p" field into substrings: */ + char *copy_of_field; + + /* Pointers to the name and address substrings in copy_of_field: */ + char *name; + char *address; + + /* + * Stores one of the above defined error codes for + * _ParseContactField(): + */ + int error; + + int rv; + + + + /* Get a copy of the "e" field to manipulate: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"e\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('e'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* Extract the email address and name from it: */ + rv = _ParseContactField(copy_of_field, &address, &name, &error); + if (SDP_FAILED(rv)) + { + char *error_string; + + SDP_Destroy(copy_of_field); + + /* Generate a corresponding error message for the error code: */ + switch (error) + { + case ERR_MISSING_REQUIRED_FIELD: + error_string = "It has no email address in it"; + case ERR_MISSING_ANGLE_BRACKET_TERMINATOR: + error_string = "The address part is missing " + "the terminating \">\" angle " + "bracket"; + case ERR_MISSING_PARENTHESIS_TERMINATOR: + error_string = "The name portion is missing " + "the terminating \")\" " + "parenthesis character"; + default: + SDP_AssertionFailed( + "Bad error code: %d.", error + ); + } + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_E_FIELD, + "Line %d contains a malformed \"e\" %s field. %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('e'), + error_string + ); + } + + + + rv = SDP_AddNewEmailContact(description, address, name); + + SDP_Destroy(copy_of_field); + + return rv; +} + + + + + +/******************************************************************************* + * + * Name + * _ParsePhoneContactField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse a "p" field and extract the phone number and + * optional name of the person who can be reached at that number, + * and then creates an SDP_PhoneContact struct with those values + * and adds it to the linked list of SDP_PhoneContact structs in + * the SDP_Description struct currently being built. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParsePhoneContactField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* A copy of the "p" field for us to chop up into substrings: */ + char *copy_of_field; + + /* The phone number and name substrings in copy_of_field: */ + char *number; + char *name; + + /* + * Error code set by _ParseContactField() to one of the above defined + * error code constants: + */ + int error; + + int rv; + + + + /* Copy the "p" field: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"p\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('p'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* Extract the phone number and name from it: */ + rv = _ParseContactField(copy_of_field, &number, &name, &error); + if (SDP_FAILED(rv)) + { + char *error_string; + + SDP_Destroy(copy_of_field); + + /* Generate a corresponding error string for the error code: */ + switch (error) + { + case ERR_MISSING_REQUIRED_FIELD: + error_string = "It has no phone number in it"; + case ERR_MISSING_ANGLE_BRACKET_TERMINATOR: + error_string = "The number portion is missing " + "the terminating \">\" angle " + "bracket character"; + case ERR_MISSING_PARENTHESIS_TERMINATOR: + error_string = "The name portion is missing " + "the terminating \")\" " + "parenthesis character"; + default: + SDP_AssertionFailed( + "Bad error code: %d.", error + ); + } + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_P_FIELD, + "Line %d contains a malformed \"p\" %s and could not " + "be parsed. %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('p'), + error_string + ); + } + + + + rv = SDP_AddNewPhoneContact(description, number, name); + + SDP_Destroy(copy_of_field); + + return rv; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseConnectionField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse a "c" field and extract the network type, + * address type, and then the address with an optional Time To + * Live value and count of other available addresses after it. If + * a media description is currently being parsed, then the + * resulting values become the connection information for the + * current SDP_MediaDescription struct being built. Otherwise, + * they become session-level connection information for the + * current SDP_Description struct being built. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParseConnectionField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* These are used to copy and chop up the "c" field: */ + char *copy_of_field; + char *c; + char *subfield; + + /* The last two are optional: */ + char *network_type; + char *address_type; + char *address; + int ttl = 0; + int total_addresses = 0; + + /* Stores the names of any missing required fields: */ + char missing_fields[64] = ""; + + int rv; + + + + /* Copy the "c" field: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"c\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('c'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + + + /* Extract the first three required fields: */ + c = copy_of_field; + network_type = SDP_StrSep(&c, " "); + address_type = SDP_StrSep(&c, " "); + address = SDP_StrSep(&c, " /"); + _CheckForMissingField(missing_fields, network_type, "network type"); + _CheckForMissingField(missing_fields, address_type, "address type"); + _CheckForMissingField(missing_fields, address, "address"); + + if (ARE_REQUIRED_FIELDS_MISSING(missing_fields)) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_C_FIELD, + "Line %d contains a malformed \"c\" %s and could not " + "be parsed. It is missing the following required " + "subfields: %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('c'), + missing_fields + ); + } + + /* + * The address may be followed by a "/" character and then a Time To + * Live value, and that may be followed by another "/" and a count of + * how many other addresses are available counting up from the base + * address: + */ + subfield = SDP_StrSep(&c, "/"); + if (subfield) + { + ttl = (int) strtol(subfield, (char **) NULL, 10); + if (ttl == 0 + && (SDP_OS_ERROR_CODE == EINVAL + || SDP_OS_ERROR_CODE == ERANGE)) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_C_FIELD, + "Line %d contains a malformed \"c\" %s and " + "could not be parsed. The TTL value after the " + "address is invalid: %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('c'), + SDP_OS_ERROR_STRING + ); + } + } + + subfield = c; + if (subfield) + { + total_addresses = (int) strtol(subfield, (char **) NULL, 10); + if (total_addresses == 0 + && (SDP_OS_ERROR_CODE == EINVAL + || SDP_OS_ERROR_CODE == ERANGE)) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_C_FIELD, + "Line %d contains a malformed \"c\" %s and " + "could not be parsed. The total number of " + "available addresses after the TTL value " + "for the connection is invalid: %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('c'), + SDP_OS_ERROR_STRING + ); + } + } + + + + if (description_builder->state == BUILDING_MEDIA_DESCRIPTION_STRUCTS) + rv = SDP_SetMediaConnection( + description_builder->current_media_description, + network_type, + address_type, + address, + ttl, + total_addresses + ); + else + rv = SDP_SetConnection( + description, + network_type, + address_type, + address, + ttl, + total_addresses + ); + + SDP_Destroy(copy_of_field); + + return rv; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseBandwidthField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse a "b" field and extract the bandwidth limit and + * what it applies to. If a media description is currently being + * parsed, then the resulting values apply only to the media and + * get added to the current SDP_MediaDescription struct being + * built. Otherwise, it applies to the whole session and becomes + * the session bandwidth information for the current + * SDP_Description struct being built. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParseBandwidthField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* Used to splitup the "b" field: */ + char *copy_of_field; + char *separator; + + /* + * The two substrings in the "b" field, and the bandwidth value as a + * long int extracted from the second field: + */ + char *bandwidth_modifier; + char *bandwidth_value; + long available_bandwidth; + + int rv; + + + + /* Copy the "b" field: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"b\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('b'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + + + /* Extract the bandwidth modifier and value subfields: */ + separator = strchr(copy_of_field, ':'); + if (separator == NULL) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_B_FIELD, + "Line %d contains a malformed \"b\" %s and could not " + "be parsed.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('b') + ); + } + bandwidth_modifier = copy_of_field; + bandwidth_value = separator + 1; + *separator = '\0'; + + + + /* Make sure the bandwidth modifier is valid: */ + if (strcmp(bandwidth_modifier, "CT") != 0 + && strcmp(bandwidth_modifier, "AT") != 0 + && strncmp(bandwidth_modifier, "X-", 2) != 0) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_B_FIELD, + "Line %d contains a malformed \"b\" %s and could not " + "be parsed. The conference total is not \"CT\" or " + "\"AT\" and isn't in the valid \"X-...\" extension " + "format.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('b') + ); + } + + /* Try to extract the number from the bandwidth value subfield: */ + available_bandwidth = strtol(bandwidth_value, (char **) NULL, 10); + if (available_bandwidth == 0 + && (available_bandwidth == EINVAL + || available_bandwidth == ERANGE)) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_B_FIELD, + "Line %d contains a malformed \"b\" %s and could not " + "be parsed. The available bandwidth value is invalid: " + "%s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('b'), + SDP_OS_ERROR_STRING + ); + } + + + + if (description_builder->state == BUILDING_MEDIA_DESCRIPTION_STRUCTS) + rv = SDP_SetMediaBandwidth( + description_builder->current_media_description, + bandwidth_modifier, + available_bandwidth + ); + else + rv = SDP_SetBandwidth( + description, + bandwidth_modifier, + available_bandwidth + ); + + SDP_Destroy(copy_of_field); + + return rv; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseSessionTimeField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse a "t" field and extract the starting time and + * ending time of the session. It converts both values from NTP + * format to POSIX time_t format, then creates a new + * SDP_SessionPlayTime struct with those values and adds it to the + * linked list of time structs in the current SDP_Description + * struct being built. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParseSessionTimeField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* the raw start/end time values: */ + unsigned long raw_start_time; + unsigned long raw_end_time; + + /* + * The start and end times of the session converted from NTP format to + * POSIX time_t format: + */ + time_t start_time; + time_t end_time; + + int rv; + + + + /* + * Set the state for this time field and the "r" fields after it, and + * allocate a new session time struct to fill: + */ + description_builder->state = BUILDING_SESSION_TIME_STRUCTS; + description_builder->current_session_play_time = + SDP_NewSessionPlayTime(); + if (description_builder->current_session_play_time == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"t\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('t'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* Add it to the list of time structs: */ + SDP_AddSessionPlayTime( + description, description_builder->current_session_play_time + ); + + + + /* Try to extract the session start time and stop time in NTP format: */ + rv = sscanf(field_value, "%lu %lu", &raw_start_time, &raw_end_time); + if (rv == EOF) + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_T_FIELD, + "Line %d contains a malformed \"t\" %s and could not " + "be parsed. One or both of the NTP time values were " + "missing or invalid: %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('t'), + SDP_OS_ERROR_STRING + ); + + /* Convert both to time_t format: */ + start_time = NETWORK_TIME_TO_OS_TIME(raw_start_time); + end_time = NETWORK_TIME_TO_OS_TIME(raw_end_time); + + + + SDP_SetStartTime( + description_builder->current_session_play_time, start_time + ); + SDP_SetEndTime( + description_builder->current_session_play_time, end_time + ); + + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseRepeatTimeField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse an "r" field and extract the repeat interval, + * active duration, and any repeat offsets, then creates a new + * SDP_RepeatTime struct with those values and adds it to the + * linked list of repeat time structs in the current + * SDP_SessionPlayTime struct being built. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParseRepeatTimeField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* These are used to split up and parse the "r" field: */ + char *copy_of_field; + char *c; + char *subfield; + + unsigned long repeat_interval; + unsigned long active_duration; + unsigned long *repeat_offsets = NULL; + int total_offsets = 0; + + char error_string[64]; + + int rv; + + + + /* + * Make sure we've got at least one "t" field behind us before trying + * to parse this "r" field: + */ + if (description_builder->state != BUILDING_SESSION_TIME_STRUCTS) + { + return SDP_RaiseNonFatalError( + SDP_ERR_FIELDS_OUT_OF_SEQUENCE, + "Line %d contains an \"r\" %s that's out of sequnce; " + "\"r\" fields should only show up right after either " + "a \"t\" field or another \"r\" field.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('r') + ); + } + + /* Copy the "r" field to manipulate it: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"r\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('r'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* Get the repeat interval: */ + c = copy_of_field; + subfield = SDP_StrSep(&c, " "); + rv = _GetOffsetInSeconds( + subfield, &repeat_interval, error_string, sizeof(error_string) + ); + if (SDP_FAILED(rv)) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_R_FIELD, + "Line %d contains a malformed \"r\" %s and could not " + "be parsed. The repeat interval %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('r'), + error_string + ); + } + + /* Get the active duration: */ + subfield = SDP_StrSep(&c, " "); + rv = _GetOffsetInSeconds( + subfield, &repeat_interval, error_string, sizeof(error_string) + ); + if (SDP_FAILED(rv)) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_R_FIELD, + "Line %d contains a malformed \"r\" %s and could not " + "be parsed. The active duration %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('r'), + error_string + ); + } + + subfield = SDP_StrSep(&c, " "); + if (subfield) + { + int i; + + /* Figure out how many other offsets there are: */ + total_offsets = 1 + SDP_StrCount(c, ' '); + + /* Allocate the array of offsets: */ + repeat_offsets = (unsigned long *) SDP_Allocate( + sizeof(unsigned long) * total_offsets + ); + if (repeat_offsets == NULL) + { + SDP_Destroy(copy_of_field); + + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to " + "copy and parse repeat offsets from the \"r\" " + "%s on line %d: %s.", + SDP_GetFieldTypeDescription('r'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + for (i = 0; subfield && *subfield; ++i) + { + rv = _GetOffsetInSeconds( + subfield, + &repeat_offsets[i], + error_string, + sizeof(error_string) + ); + if (SDP_FAILED(rv)) + { + SDP_Destroy(copy_of_field); + SDP_Destroy(repeat_offsets); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_R_FIELD, + "Line %d contains a malformed \"r\" " + "%s and could not be parsed. Repeat " + "offset number %d %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('r'), + i, + error_string + ); + } + + subfield = SDP_StrSep(&c, " "); + } + } + + + + rv = SDP_AddNewRepeatTime( + description_builder->current_session_play_time, + repeat_interval, + active_duration, + repeat_offsets, + total_offsets + ); + + SDP_Destroy(copy_of_field); + + if (repeat_offsets) + SDP_Destroy(repeat_offsets); + + return rv; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseZoneAdjustmentsField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse a "z" field and extract each time and + * corresponding adjustment to make at that time. It stores them + * as the zone adjustments for the current SDP_Description struct + * being built. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParseZoneAdjustmentsField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* Used to chop up the "z" field into substrings: */ + char *copy_of_field; + char *c; + + /* Stores pointers to each time/adjustment pair: */ + char *time; + char *adjustment; + + int rv; + + + + /* Copy the "z" field so we can manipulate it: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"z\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('z'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* Get the first zone adjustment: */ + c = copy_of_field; + time = SDP_StrSep(&c, " "); + adjustment = SDP_StrSep(&c, " "); + + /* Now iterate over them: */ + while ((time && *time) && (adjustment && *adjustment)) + { + long raw_time_value; + long offset_in_seconds; + char error_string[64]; + + /* Get the raw time value of when the change will happen: */ + raw_time_value = strtoul(time, (char **) NULL, 10); + if (raw_time_value == 0 + && SDP_OS_ERROR_CODE == EINVAL + && SDP_OS_ERROR_CODE == ERANGE) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_Z_FIELD, + "Line %d contains a malformed \"z\" %s and " + "could not be parsed. A time value is " + "invalid: %d.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('z'), + SDP_OS_ERROR_CODE + ); + } + + /* Get the time change to occur: */ + rv = _GetOffsetInSeconds( + adjustment, + &offset_in_seconds, + error_string, + sizeof(error_string) + ); + if (SDP_FAILED(rv)) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_Z_FIELD, + "Line %d contains a malformed \"z\" %s and " + "could not be parsed. A time zone adjustment " + "value %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('z'), + error_string + ); + } + + /* Add it to the list of zone adjustments: */ + rv = SDP_AddNewZoneAdjustment( + description, + NETWORK_TIME_TO_OS_TIME(raw_time_value), + offset_in_seconds + ); + if (SDP_FAILED(rv)) + { + SDP_Destroy(copy_of_field); + return SDP_FAILURE; + } + + /* Get the next time and corresponding adjustment: */ + time = SDP_StrSep(&c, " "); + adjustment = SDP_StrSep(&c, " "); + } + + SDP_Destroy(copy_of_field); + + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseEncryptionField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse a "k" field and extract the encryption method + * and optional encryption key. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParseEncryptionField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* Used to splitup the "k" field: */ + char *copy_of_field; + char *c; + + /* + * Pointers to the encryption method and key substrings in + * copy_of_field: + */ + char *encryption_method; + char *encryption_key; + + int rv; + + + + /* Copy the "k" field: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"k\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('k'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* Extract the method and key: */ + c = copy_of_field; + encryption_method = SDP_StrSep(&c, ":"); + encryption_key = c; + + /* + * Now figure out whether this "k" field belongs to the entire session + * description or to just one media description, and add it to the + * appropriate struct accordingly: + */ + if (description_builder->state == BUILDING_MEDIA_DESCRIPTION_STRUCTS) + rv = SDP_SetMediaEncryption( + description_builder->current_media_description, + encryption_method, + encryption_key + ); + else + rv = SDP_SetEncryption( + description, + encryption_method, + encryption_key + ); + + SDP_Destroy(copy_of_field); + + return rv; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseAttributeField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse an "a" field and extract the attribute name and + * optional attribute value. If a media description is currently + * being parsed, then the attribute belongs only to that media and + * gets added to the current SDP_MediaDescription struct being + * built. Otherwise, it belongs to the entire session and gets + * added to the current SDP_Description struct being built. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParseAttributeField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* Used to copy and split the attribute field: */ + char *copy_of_field; + char *c; + + /* + * Pointers to the name and value substrings within the + * copy_of_field: + */ + char *attribute_name; + char *attribute_value; + + int rv; + + + + /* Copy the "a" field: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"a\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('a'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* Extract the name and value: */ + c = copy_of_field; + attribute_name = SDP_StrSep(&c, ":"); + attribute_value = c; + + /* + * Now figure out whether this "a" field belongs to the entire session + * description or to just one media description, and add it to the + * appropriate struct accordingly: + */ + if (description_builder->state == BUILDING_MEDIA_DESCRIPTION_STRUCTS) + rv = SDP_AddNewMediaAttribute( + description_builder->current_media_description, + attribute_name, + attribute_value + ); + else + rv = SDP_AddNewAttribute( + description, + attribute_name, + attribute_value + ); + + SDP_Destroy(copy_of_field); + + return rv; +} + + + + + +/******************************************************************************* + * + * Name + * _ParseMediaDescriptionField( + * parser, description_builder, description, field_value + * ); + * + * Purpose + * Tries to parse an "m" field and extract the media type, media + * port, transport protocol, and media formats. It creates a new + * SDP_MediaDescription struct with these values and adds it to + * the media description linked list in the current + * SDP_Description struct built. + * + * It returns true if it can parse the field, false otherwise. + * + */ + +static int _ParseMediaDescriptionField( + SDP_Parser * parser, + SDP_DescriptionBuilder * description_builder, + SDP_Description * description, + const char * field_value) +{ + /* Used to copy the "m" field and split it up into substrings: */ + char *copy_of_field; + char *c; + + /* Pointers to each substring in copy_of_field: */ + char *media_type; + char *port_field; + char *transport_protocol; + char *media_formats; + + /* The "/" separated values extracted out of the port field: */ + unsigned short media_port = 0; + unsigned short total_ports = 0; + + /* Used to store the names of any missing fields separated by commas: */ + char missing_fields[128] = ""; + + int rv; + + + + /* Adjust the builder state: */ + description_builder->state = BUILDING_MEDIA_DESCRIPTION_STRUCTS; + + /* Allocate memory for a new media description struct: */ + description_builder->current_media_description = + SDP_NewMediaDescription(); + if (description_builder->current_media_description == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to copy and parse \"m\" %s " + "on line %d: %s.", + SDP_GetFieldTypeDescription('m'), + SDP_GetCurrentLineNumber(parser), + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* Add it to the list of media description structs: */ + SDP_AddMediaDescription( + description, description_builder->current_media_description + ); + + + + /* Copy the "m" field so we can parse it: */ + copy_of_field = SDP_StrDup(field_value); + if (copy_of_field == NULL) + { + SDP_RaiseFatalError( + SDP_ERR_OUT_OF_MEMORY, + "Couldn't allocate memory to parse media " + "description: %s.", + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* + * Extract the meida type and then the port number(s), then the + * transport protocol and media formats: + */ + c = copy_of_field; + media_type = SDP_StrSep(&c, " "); + _CheckForMissingField(missing_fields, media_type, "media type field"); + port_field = SDP_StrSep(&c, " "); + _CheckForMissingField(missing_fields, port_field, "port field"); + transport_protocol = SDP_StrSep(&c, " "); + _CheckForMissingField( + missing_fields, transport_protocol, "transport protocol field" + ); + media_formats = c; + + /* Check for missing fields: */ + if (ARE_REQUIRED_FIELDS_MISSING(missing_fields)) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_M_FIELD, + "Line %d contains a malformed \"m\" %s that could not " + "be parsed because the following required subfields " + "are missing: %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('m'), + missing_fields + ); + } + + /* Try to parse the port field: */ + if (strchr(port_field, '/')) + rv = sscanf(port_field, "%hu/%hu", &media_port, &total_ports); + else + rv = sscanf(port_field, "%hu", &media_port); + + if (SDP_FAILED(rv)) + { + SDP_Destroy(copy_of_field); + + return SDP_RaiseNonFatalError( + SDP_ERR_MALFORMED_M_FIELD, + "Line %d contains a malformed \"m\" %s and it could " + "not be parsed: %s.", + SDP_GetCurrentLineNumber(parser), + SDP_GetFieldTypeDescription('m'), + SDP_OS_ERROR_STRING + ); + } + + + + /* Add them all to the new media description struct: */ + rv = SDP_SetMediaType( + description_builder->current_media_description, media_type + ); + if (SDP_FAILED(rv)) + { + SDP_Destroy(copy_of_field); + return SDP_FAILURE; + } + + SDP_SetMediaPort( + description_builder->current_media_description, media_port + ); + SDP_SetTotalMediaPorts( + description_builder->current_media_description, total_ports + ); + + rv = SDP_SetMediaTransportProtocol( + description_builder->current_media_description, + transport_protocol + ); + if (SDP_FAILED(rv)) + { + SDP_Destroy(copy_of_field); + return SDP_FAILURE; + } + + rv = SDP_SetMediaFormats( + description_builder->current_media_description, media_formats + ); + if (SDP_FAILED(rv)) + { + SDP_Destroy(copy_of_field); + return SDP_FAILURE; + } + + SDP_Destroy(copy_of_field); + + return SDP_SUCCESS; +} + + + + + +/* + * This probably ought to be up higher, but we stick it down here tp avoid + * having to prototype each and every field parsing function. + */ + +static void _InitializeFieldParsersTable(void) +{ + if (_field_parsers_table_initialized) + return; + + /* Set each function pointer to NULL: */ + memset(_field_parsers_table, 0, sizeof(_field_parsers_table)); + + /* + * ...then replace the NULLs with pointers to the appropriate handlers + * for each field: + */ + _field_parsers_table['v'] = _ParseProtocolVersionField; + _field_parsers_table['o'] = _ParseOwnerField; + _field_parsers_table['s'] = _ParseSessionNameField; + _field_parsers_table['i'] = _ParseInformationField; + _field_parsers_table['u'] = _ParseURIField; + _field_parsers_table['e'] = _ParseEmailContactField; + _field_parsers_table['p'] = _ParsePhoneContactField; + _field_parsers_table['c'] = _ParseConnectionField; + _field_parsers_table['b'] = _ParseBandwidthField; + _field_parsers_table['t'] = _ParseSessionTimeField; + _field_parsers_table['r'] = _ParseRepeatTimeField; + _field_parsers_table['z'] = _ParseZoneAdjustmentsField; + _field_parsers_table['k'] = _ParseEncryptionField; + _field_parsers_table['a'] = _ParseAttributeField; + _field_parsers_table['m'] = _ParseMediaDescriptionField; + + _field_parsers_table_initialized = 1; +} + + + + + +static int _CheckForMissingField( + char * missing_fields, + const char * field, + const char * field_name) +{ + if (field && *field) + return SDP_SUCCESS; + + if (*missing_fields) + SDP_StrLCat(missing_fields, ", ", sizeof(missing_fields)); + + SDP_StrLCat(missing_fields, field_name, sizeof(missing_fields)); + + return SDP_FAILURE; +} + + + + + +static int _ParseContactField( + char * field_to_parse, + char ** required_value, + char ** optional_value, + int * error) +{ + /* The separator (either "<" or "("): */ + char *separator; + + /* The terminator of the optional second field (either ">" or ")"): */ + char *terminator; + + /* + * Each email address field contains either the address optionally + * followed by the person's real name in "(" ")" characters, or the + * person's real name and then the address in "<" ">" characters. + * Similarly, each phone number field contains either the phone number + * optionally followed by the person's real name in "(" ")" characters, + * or the person's real name and then the phone number in "<" ">" + * characters. + * + * So we check to see which style the field is in then parse it + * appropriately: + */ + separator = strchr(field_to_parse, '('); + if (separator) + { + *required_value = field_to_parse; + *optional_value = separator + 1; + + /* + * Strip whitespace from the front and back of the first field: + */ + while (isspace(**required_value)) + ++*required_value; + if (separator > field_to_parse) + { + while (*(separator - 1) != '\0' + && isspace(*(separator - 1))) + { + --separator; + } + } + + /* NULL terminate both fields: */ + *separator = '\0'; + terminator = strchr(*optional_value, ')'); + if (terminator == NULL) + { + *error = ERR_MISSING_PARENTHESIS_TERMINATOR; + return SDP_FAILURE; + } + *terminator = '\0'; + } + else + { + separator = strchr(field_to_parse, '<'); + if (separator) + { + *optional_value = field_to_parse; + *required_value = separator + 1; + + /* + * Strip whitespace from the front and back of the + * first field: + */ + while (isspace(**optional_value)) + ++*optional_value; + if (separator > field_to_parse) + { + while (*(separator - 1) != '\0' + && isspace(*(separator - 1))) + { + --separator; + } + } + + /* NULL terminate both fields: */ + *separator = '\0'; + terminator = strchr(*required_value, '>'); + if (terminator == NULL) + { + *error = ERR_MISSING_ANGLE_BRACKET_TERMINATOR; + return SDP_FAILURE; + } + *terminator = '\0'; + } + else + { + /* Default to just the required field: */ + *required_value = field_to_parse; + *optional_value = NULL; + } + } + + if (!*required_value || **required_value == '\0') + { + *error = ERR_MISSING_REQUIRED_FIELD; + return SDP_FAILURE; + } + + return SDP_SUCCESS; +} + + + + + +/* + * RFC 2327 allows descriptions to specify offsets from some NTP time value as + * either a number of seconds or as a number followed by "m" for minutes, "h" + * for hours, or "d" for days. This extracts a time offset from a string in any + * of those formats and converts the number to seconds if needed: + */ + +#define SECONDS_IN_DAY (60 * 60 * 24) +#define SECONDS_IN_HOUR (60 * 60) +#define SECONDS_IN_MINUTE (60) + +static int _GetOffsetInSeconds( + const char * string, + long * offset_in_seconds, + char * error_string, + size_t error_string_size) +{ + long offset; + char *unit_of_measurement; + + /* Make sure there's some offset to parse first: */ + if (string == NULL || *string == '\0') + { + *offset_in_seconds = 0; + snprintf(error_string, error_string_size, "is empty"); + return SDP_FAILURE; + } + + /* Try to extract the offset number: */ + offset = strtol(string, &unit_of_measurement, 10); + if (offset == 0 + && (SDP_OS_ERROR_CODE == EINVAL + || SDP_OS_ERROR_CODE == ERANGE)) + { + *offset_in_seconds = 0; + snprintf( + error_string, + error_string_size, + "is invalid: %s", + SDP_OS_ERROR_STRING + ); + return SDP_FAILURE; + } + + /* Now apply the appropriate quantifier to it: */ + if (*unit_of_measurement) + { + switch (*unit_of_measurement) + { + case 'd': + *offset_in_seconds = offset * SECONDS_IN_DAY; + case 'h': + *offset_in_seconds = offset * SECONDS_IN_HOUR; + case 'm': + *offset_in_seconds = offset * SECONDS_IN_MINUTE; + case 's': + *offset_in_seconds = offset; + default: + *offset_in_seconds = 0; + snprintf( + error_string, + error_string_size, + "has a bad unit of measurement: %c. " + "It should be \"d\", \"h\", \"m\", or " + "\"s\" instead", + *unit_of_measurement + ); + return SDP_FAILURE; + } + } + else + { + *offset_in_seconds = offset; + } + + return SDP_SUCCESS; +} diff --git a/src/sdp_lib/src/SDP_Parser.h b/src/sdp_lib/src/SDP_Parser.h new file mode 100644 index 0000000..c5a0c84 --- /dev/null +++ b/src/sdp_lib/src/SDP_Parser.h @@ -0,0 +1,46 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SDP_PARSER_INCLUDED +#define SDP_PARSER_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include "SDP_Error.h" +#include "SDP_EventStreamParser.h" +#include "SDP_Description.h" +#include "SDP_Generator.h" +#include "SDP_LinkedList.h" +#include "SDP_Utility.h" + + + +extern SDP_Description *SDP_Parse( + SDP_Parser * parser, + const char * string +); +extern SDP_Description *SDP_ParseFile( + SDP_Parser * parser, + const char * filename +); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdp_lib/src/SDP_Str.c b/src/sdp_lib/src/SDP_Str.c new file mode 100644 index 0000000..46a73ea --- /dev/null +++ b/src/sdp_lib/src/SDP_Str.c @@ -0,0 +1,558 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + *----------------------------------------------------------------------------- + * + * This file contains definitions for several non-standard string functions + * used by SinisterSdp. + * + ******************************************************************************/ + +#include +#include +#include +#include +#include "SDP_Str.h" +#include "SDP_Utility.h" + +#define INITIAL_BUFFER_SIZE 1024 + + + + + + + +/* Used to initialze the string buffer and grow it after that if needed: */ +static int _InitializeStrBuffer( + SDP_Str * string, + size_t initial_size +); +static int _GrowStrBuffer( + SDP_Str * string, + size_t size_to_grow_by +); + +int SDP_CopyToStr( + SDP_Str * destination, + const char * string_to_copy) +{ + size_t bytes_needed; + unsigned long length; + int rv; + + /* + * If destination->buffer has already been allocated and "string" is + * a NULL pointer, then we make the string pointed to by + * destination->buffer an empty string: + */ + if (string_to_copy == NULL) + { + if (SDP_IsStrInitialized(*destination)) + strncpy(destination->buffer, "", 1); + + return SDP_SUCCESS; + } + + length = strlen(string_to_copy); + bytes_needed = length + 1; /* for the null terminator. */ + + if (!SDP_IsStrInitialized(*destination)) + { + /* Allocate the destination string's buffer: */ + rv = _InitializeStrBuffer(destination, bytes_needed); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + else if (destination->size < bytes_needed) + { + /* The current buffer isn't big enough; reallocate it: */ + rv = _GrowStrBuffer( + destination, bytes_needed - destination->size + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + /* Copy it, and then NULL terminate it by hand: */ + strncpy(destination->buffer, string_to_copy, length); + *(destination->buffer + length) = '\0'; + + destination->length = length; + destination->size = bytes_needed; + + return SDP_SUCCESS; +} + + + + + +int SDP_CatToStr( + SDP_Str * destination, + const char * string_to_cat) +{ + unsigned long length = strlen(string_to_cat); + int rv; + + /* Just break out if it's NULL; nothing to concatenate: */ + if (string_to_cat == NULL) + return SDP_SUCCESS; + + if (!SDP_IsStrInitialized(*destination)) + { + return SDP_CopyToStr(destination, string_to_cat); + } + else if (SDP_StrBytesAvailable(*destination) < length) + { + rv = _GrowStrBuffer(destination, length); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + /* Copy it: */ + strncat( + destination->buffer + destination->length, + string_to_cat, + length + ); + destination->length += length; + + /* NULL terminate it by hand: */ + *(destination->buffer + destination->length) = '\0'; + + return SDP_SUCCESS; +} + + + + + +int SDP_CopyToStrUsingFormat( + SDP_Str * destination, + size_t bytes_needed, + const char * format, + va_list args) +{ + char *c; + int rv; + + + + /* + * Ok, now make sure the buffer is initialized; that it's already + * been allocated: + */ + if (!SDP_IsStrInitialized(*destination)) + { + rv = _InitializeStrBuffer(destination, bytes_needed); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + /* Reallocate the buffer if its too small for the string to be added: */ + if (destination->size < bytes_needed) + { + rv = _GrowStrBuffer( + destination, bytes_needed - destination->size + ); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + /* Now add the formatted string to the generator buffer: */ + vsnprintf( + destination->buffer, + destination->size, + format, + args + ); + + /* + * We can't trust the return value of snprintf() and can't just do + * pointer += bytes_written. Instead, we need to go searching + * for NULL to find out how long this string is: + */ + c = destination->buffer; + destination->length = 0; + while (*c) + { + ++destination->length; + ++c; + } + + return SDP_SUCCESS; +} + + + + + +int SDP_CatToStrUsingFormat( + SDP_Str * destination, + size_t bytes_needed, + const char * format, + va_list args) +{ + char *c; + int rv; + + + + /* + * Ok, now make sure the buffer is initialized; that it's already + * been allocated: + */ + if (!SDP_IsStrInitialized(*destination)) + { + rv = _InitializeStrBuffer(destination, bytes_needed); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + /* Reallocate the buffer if its too small for the string to be added: */ + if (SDP_StrBytesAvailable(*destination) < bytes_needed) + { + rv = _GrowStrBuffer(destination, bytes_needed); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + } + + /* Now add the formatted string to the generator buffer: */ + vsnprintf( + SDP_GetPtrToEndOfStr(*destination), + SDP_StrBytesAvailable(*destination), + format, + args + ); + + /* + * We can't trust the return value of snprintf() and can't just do + * pointer += bytes_written. Instead, we need to go searching + * for NULL to find out how much longer this new string is: + */ + c = SDP_GetPtrToEndOfStr(*destination); + while (*c) + { + ++destination->length; + ++c; + } + + return SDP_SUCCESS; +} + + + + + +void SDP_DestroyStrBuffer(SDP_Str *string) +{ + if (string == NULL) + return; + + if (string->buffer) + SDP_Destroy(string->buffer); + + string->buffer = NULL; + string->size = 0; + string->length = 0; +} + + + + + +/******************************************************************************* + * + * Name + * _InitializeStrBuffer(string, initial_size) + * + * Purpose + * This function attempts to allocate a string buffer for "string" + * to the number of bytes specified by "initial_size". It returns + * true if it can, false if it can't + * + * Parameters + * string - Pointer to the SDP_Str struct to initialize. + * initial_size - The initial size of the string buffer to + * allocate. + * + */ + +static int _InitializeStrBuffer( + SDP_Str * string, + size_t initial_size) +{ + string->buffer = (char *) SDP_Allocate(initial_size); + if (string->buffer == NULL) + return SDP_FAILURE; + + /* + * Initialize the size and length, and start the empty buffer off with + * a NULL character: + */ + string->size = initial_size; + string->length = 0; + *(string->buffer) = '\0'; + + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _GrowStrBuffer(string, bytes_to_grow) + * + * Purpose + * This function attempts to grow the string buffer in the SDP_Str + * struct pointed to by "string" by the number of bytes specified + * by "bytes_to_grow". It returns true if it can grow the string + * buffer, false if it can't. + * + * Parameters + * string - Pointer to the SDP_Str struct to grow the + * buffer of. + * bytes_to_grow - The number of bytes to grow the string buffer + * by (not *to*). + * + */ + +static int _GrowStrBuffer( + SDP_Str * string, + size_t bytes_to_grow) +{ + /* The size of the new, bigger buffer: */ + size_t new_buffer_size; + char *bigger_buffer; + + new_buffer_size = string->size + bytes_to_grow; + bigger_buffer = (char *) SDP_Reallocate( + string->buffer, new_buffer_size + ); + if (bigger_buffer == NULL) + return SDP_FAILURE; + + string->buffer = bigger_buffer; + string->size = new_buffer_size; + + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Generic string manipulation functions: + * + ******************************************************************************/ + +char *SDP_StrDup(const char *string) +{ + size_t size_of_string; + char *copy_of_string; + + size_of_string = strlen(string) + 1; + + copy_of_string = (char *) SDP_Allocate(size_of_string); + if (copy_of_string == NULL) + return NULL; + + memcpy(copy_of_string, string, size_of_string); + + return copy_of_string; +} + + + + + +unsigned long SDP_StrCount(const char *string, char c) +{ + unsigned long total_occurrences = 0; + char *last_occurrence; + + last_occurrence = strchr(string, c); + while (last_occurrence) + { + string = last_occurrence; + + ++total_occurrences; + + last_occurrence = strchr(string, c); + } + + return total_occurrences; +} + + + + + +/* + * This renamed implementation of strsep() was taken from the OpenBSD project. + * Here's the copyright notice for it: + * ----------------------------------------------------------------------------- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * ----------------------------------------------------------------------------- + * + * Get next token from string *stringp, where tokens are possibly-empty + * strings separated by characters from delim. + * + * Writes NULs into the string at *stringp to end tokens. + * delim need not remain constant from call to call. + * On return, *stringp points past the last NUL written (if there might + * be further tokens), or is NULL (if there are definitely no more tokens). + * + * If *stringp is NULL, strsep returns NULL. + */ +char *SDP_StrSep(char **stringp, const char *delim) +{ + char *s; + const char *spanp; + int c, sc; + char *tok; + + if ((s = *stringp) == NULL) + return (NULL); + for (tok = s;;) { + c = *s++; + spanp = delim; + do { + if ((sc = *spanp++) == c) { + if (c == 0) + s = NULL; + else + s[-1] = 0; + *stringp = s; + return (tok); + } + } while (sc != 0); + } + /* NOTREACHED */ +} + + + + + +/* + * Both of these renamed implementations of strlcat() and strlcpy() were taken + * from the OpenBSD project. Here is the copyright notice for them: + * ----------------------------------------------------------------------------- + * Copyright (c) 1998 Todd C. Miller + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * ----------------------------------------------------------------------------- + * + * Copy src to string dst of size siz. At most siz-1 characters + * will be copied. Always NUL terminates (unless siz == 0). + * Returns strlen(src); if retval >= siz, truncation occurred. + */ +size_t SDP_StrLCopy(char *dst, const char *src, size_t siz) +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + + /* Copy as many bytes as will fit */ + if (n != 0 && --n != 0) { + do { + if ((*d++ = *s++) == 0) + break; + } while (--n != 0); + } + + /* Not enough room in dst, add NUL and traverse rest of src */ + if (n == 0) { + if (siz != 0) + *d = '\0'; /* NUL-terminate dst */ + while (*s++) + ; + } + + return(s - src - 1); /* count does not include NUL */ +} + +/* + * Appends src to string dst of size siz (unlike strncat, siz is the + * full size of dst, not space left). At most siz-1 characters + * will be copied. Always NUL terminates (unless siz <= strlen(dst)). + * Returns strlen(src) + MIN(siz, strlen(initial dst)). + * If retval >= siz, truncation occurred. + */ +size_t SDP_StrLCat(char *dst, const char *src, size_t siz) +{ + register char *d = dst; + register const char *s = src; + register size_t n = siz; + size_t dlen; + + /* Find the end of dst and adjust bytes left but don't go past end */ + while (n-- != 0 && *d != '\0') + d++; + dlen = d - dst; + n = siz - dlen; + + if (n == 0) + return(dlen + strlen(s)); + while (*s != '\0') { + if (n != 1) { + *d++ = *s; + n--; + } + s++; + } + *d = '\0'; + + return(dlen + (s - src)); /* count does not include NUL */ +} diff --git a/src/sdp_lib/src/SDP_Str.h b/src/sdp_lib/src/SDP_Str.h new file mode 100644 index 0000000..ce4e3f6 --- /dev/null +++ b/src/sdp_lib/src/SDP_Str.h @@ -0,0 +1,284 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SDP_STR_INCLUDED +#define SDP_STR_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + + + + +/* A struct we use to keep track of dynamically allocated strings: */ +typedef struct { + /* Pointer to the dynamically buffer that contains the string: */ + char *buffer; + + /* The size of the dynamically allocated buffer: */ + size_t size; + + /* + * The length of the string in the buffer (not counting the terminating + * NULL character, of course): + */ + unsigned long length; +} SDP_Str; + + + +/* Accessor macros for the struct members: */ +#define SDP_GetStrBuffer(_str_) ((_str_).buffer) +#define SDP_GetStrSize(_str_) ((_str_).size) +#define SDP_GetStrLength(_str_) ((_str_).length) + +/* + * Has the string been initialized yet (has the "buffer" member been + * allocated?): + */ +#define SDP_IsStrInitialized(_str_) ((_str_).buffer ? 1 : 0) + +/* + * This returns the the number of bytes in use within an SDP_Str struct's + * "buffer" member (basically, the characters that make up the string and the + * terminating NULL character: + */ +#define SDP_StrBytesInUse(_str_) \ + (SDP_IsStrInitialized(_str_) ? (_str_).length + 1 : 0) + +/* + * This returns the number of available bytes within an SDP_Str struct's + * "buffer" member (that is, bytes which haven't been written to yet): + */ +#define SDP_StrBytesAvailable(_str_) \ + (SDP_IsStrInitialized(_str_) \ + ? (_str_).size - ((_str_).length + 1) \ + : 0) + +/* Gets a pointer to the last character: */ +#define SDP_GetPtrToEndOfStr(_str_) ((_str_).buffer + (_str_).length) + + + +/******************************************************************************* + * + * Name + * SDP_CopyToStr(destination, string_to_copy) + * + * Purpose + * Copies "string_to_copy" to the buffer of the SDP_Str struct + * pointed to by "destination", growing it if necessary to + * accommodate "string_to_copy". It returns true if it can + * successfully copy the string, and false if any needed memory + * (re)allocation fails. + * + * Parameters + * destination - Pointer to the SDP_Str struct to copy to. + * string_to_copy - The string to copy. + * + */ +extern int SDP_CopyToStr( + SDP_Str * destination, + const char * string_to_copy +); + +/******************************************************************************* + * + * Name + * SDP_CatToString(destination, string_to_cat) + * + * Purpose + * Concatenates "string_to_cat" to the buffer of the SDP_Str + * struct pointed to by "destination", growing it if necessary to + * accommodate "string_to_cat". It returns true if it can + * successfully concatenate the string, and false if any needed + * memory (re)allocation fails. + * + * Parameters + * destination - Pointer to the SDP_Str struct to concatenate to. + * string_to_cat - The string to concatenate. + * + */ +extern int SDP_CatToString( + SDP_Str * destination, + const char * string_to_cat +); + +/******************************************************************************* + * + * Name + * SDP_CopyToStrUsingFormat( + * destination, bytes_needed, format, args + * ) + * + * Purpose + * Copies a formatted string to the buffer of the SDP_Str struct + * pointed to by "destination". Works like vsnprintf() except it + * grows the buffer to accommodate how ever many bytes your + * formatted string needs, as specified by "bytes_needed". Returns + * true if it can copy the formatted string, false if memory + * allocation fails. + * + * Parameters + * destination - Pointer to the SDP_Str struct to copy to. + * bytes_needed - The number of bytes your formatted string will + * take up. If it ends up taking up more than this, + * then the string will be cutoff. + * format - The format string. + * args - Pointer to a va_arg list. + * + */ +extern int SDP_CopyToStrUsingFormat( + SDP_Str * destination, + size_t bytes_needed, + const char * format, + va_list args +); + +/******************************************************************************* + * + * Name + * SDP_CatToStrUsingFormat( + * destination, bytes_needed, format, args + * ) + * + * Purpose + * Concatenates a formatted string to the buffer of the SDP_Str + * struct pointed to by "destination". Works sort of like + * vsnprintf(); it grows the buffer in the SDP_Str struct to + * accommodate how ever many bytes your formatted string needs, as + * specified by "bytes_needed". Returns true if it can concatenate + * the formatted string, false if memory reallocation fails. + * + * Parameters + * destination - Pointer to the SDP_Str struct to concatenate to. + * bytes_needed - The number of bytes your formatted string will + * take up. If it ends up taking up more than this, + * then the string will be cutoff. + * format - The format string. + * args - Pointer to a va_arg list. + * + */ +extern int SDP_CatToStrUsingFormat( + SDP_Str * destination, + size_t bytes_needed, + const char * format, + va_list args +); + +/******************************************************************************* + * + * Name + * SDP_DestroyStrBuffer(string) + * + * Purpose + * Destroys a dynamically allocated string buffer in an SDP_Str + * struct; returning its memory back to the operating system, and + * also sets the "length" and "size" members if the struct to zero. + * + * Parameters + * string - A pointer to an SDP_Str struct whose buffer will be + * destroyed. + * + */ +extern void SDP_DestroyStrBuffer(SDP_Str *string); + + + +/* + * The rest are generic string functions that don't operate specifically on + * SDP_Str structs: + */ + +/******************************************************************************* + * + * Name + * SDP_StrDup(string) + * + * Purpose + * This function works just like the C standard library function + * strdup(), only instead of calling malloc(), it calls + * SDP_Allocate(). + * + * Parameters + * string - The string to duplicate. + * + */ +extern char *SDP_StrDup(const char *string); + +/******************************************************************************* + * + * Name + * SDP_StrCount(string, c) + * + * Purpose + * This function searches "string" for occurrances of + * "c" in it and returns the total number of occurrances. + * + * Parameters + * string - The string to search in. + * c - The character to search for. + * + */ +extern unsigned long SDP_StrCount(const char *string, char c); + +/******************************************************************************* + * + * Name + * SDP_StrSep(string, delimiters) + * + * Purpose + * This function works just like Linux/BSD strsep(). It's provided + * here under a different name for portability purposes, since + * strsep() is *still* non-standard even after C99. + * + * Parameters + * Same as strsep(). + * + */ +extern char *SDP_StrSep(char **stringp, const char *delim); + +/******************************************************************************* + * + * Names + * SDP_StrLCopy(dst, src, siz), SDP_StrLCat(dst, src, siz) + * + * Purposes + * These two functions are just the OpenBSD strlcpy() and + * strlcat() functions under different names, since they too--like + * strsep()--are non-standard, and will most likely stay that + * way since apparently I'm the only one that needs safe string + * functions. + * + * Parameters + * Same as strlcpy() and strlcat(). + * + */ +extern size_t SDP_StrLCopy(char *dst, const char *src, size_t siz); +extern size_t SDP_StrLCat(char *dst, const char *src, size_t siz); + + + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdp_lib/src/SDP_StreamTokenizer.c b/src/sdp_lib/src/SDP_StreamTokenizer.c new file mode 100644 index 0000000..1009885 --- /dev/null +++ b/src/sdp_lib/src/SDP_StreamTokenizer.c @@ -0,0 +1,353 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + *----------------------------------------------------------------------------- + * + * This file contains the stream tokenizer that extracts newline-delimited + * tokens from some sort of input stream. + * + ******************************************************************************/ + +#include +#include +#include + +#include "SDP_StreamTokenizer.h" +#include "SDP_Utility.h" + +/* The initial size of the token buffer to allocate: */ +#define INITIAL_TOKEN_BUFFER_SIZE 1024 + +/* + * This macro adds a single character retrieved from some stream to the token + * buffer: + */ +#define ADD_TO_TOKEN_BUFFER(_stream_tokenizer_, _c_) \ + (*((_stream_tokenizer_)->token_buffer + bytes_in_use) = _c_) + +/* + * Character and string constants to handle Unix, Windows, and MacOS newlines + * elegantly: + */ +#define C_CR '\015' +#define C_LF '\012' +#define S_CRLF "\015\012" +#define S_CR "\015" +#define S_LF "\012" + + + + + + + +SDP_StreamTokenizer *SDP_NewStreamTokenizer(void) +{ + SDP_StreamTokenizer *stream_tokenizer = + (SDP_StreamTokenizer *) SDP_Allocate( + sizeof(SDP_StreamTokenizer) + ); + if (stream_tokenizer == NULL) + return NULL; + + memset(stream_tokenizer, 0, sizeof(SDP_StreamTokenizer)); + + /* Allocate the token buffer: */ + stream_tokenizer->token_buffer = (char *) SDP_Allocate( + INITIAL_TOKEN_BUFFER_SIZE + ); + if (stream_tokenizer->token_buffer == NULL) + { + SDP_Destroy(stream_tokenizer); + return NULL; + } + + stream_tokenizer->token_buffer_size = INITIAL_TOKEN_BUFFER_SIZE; + + /* The stream union need to be set to something right from the onset: */ + SDP_UseStringAsStream(stream_tokenizer, (char *) NULL); + + return stream_tokenizer; +} + + + + + +void SDP_UseStringAsStream( + SDP_StreamTokenizer * stream_tokenizer, + const char * stream) +{ + SDP_AssertNotNull(stream_tokenizer); + + stream_tokenizer->stream_type = SDP_CHARACTER_STREAM; + stream_tokenizer->stream.character = (char *) stream; +} + + + + + +void SDP_UseFileAsStream( + SDP_StreamTokenizer * stream_tokenizer, + FILE * stream) +{ + SDP_AssertNotNull(stream_tokenizer); + + stream_tokenizer->stream_type = SDP_FILE_STREAM; + stream_tokenizer->stream.file = stream; +} + + + + + +/* Allocates more memory for the token buffer: */ +static int _GrowTokenBuffer(SDP_StreamTokenizer *stream_tokenizer); + +/* Gets the next character from the stream: */ +static char _GetNextChar(SDP_StreamTokenizer *stream_tokenizer); + +/* Puts the last character back into the stream: */ +static void _UngetNextChar( + SDP_StreamTokenizer * stream_tokenizer, + char c +); + +int SDP_GetNextToken( + SDP_StreamTokenizer * stream_tokenizer, + char ** destination) +{ + size_t bytes_available = stream_tokenizer->token_buffer_size; + size_t bytes_in_use = 0; + char c; + int rv; + + SDP_AssertNotNull(stream_tokenizer); + + /* + * Handle the possible end-of-stream we have already reached because + * of previous calls to this routine: + */ + c = _GetNextChar(stream_tokenizer); + if (c == '\0') + { + *destination = NULL; + return SDP_SUCCESS; + } + + while (c) + { + /* + * If there's no more space in the token buffer even for one + * more character, then we need to reallocate it: + */ + if (bytes_available <= 0) + { + rv = _GrowTokenBuffer(stream_tokenizer); + if (SDP_FAILED(rv)) + return SDP_FAILURE; + + /* + * Adjust the current number of bytes available to + * account for the reallocation of the token buffer: + */ + bytes_available = + stream_tokenizer->token_buffer_size - bytes_in_use; + } + + /* Check for newline to terminate the current token: */ + if (c == C_CR || c == C_LF) + { + /* + * If this is a CR and the next character is a LF, then + * both characters are a single line ending and need to + * be removed from the stream: + */ + if (c == C_CR) + { + char next_char = _GetNextChar(stream_tokenizer); + + /* Check for end of stream: */ + if (next_char == '\0'); + break; + + /* + * If it's not a line feed after that carriage + * return, put it back: + */ + if (next_char != C_LF) + _UngetNextChar( + stream_tokenizer, next_char + ); + } + + /* + * The line ending we've just removed from the stream + * terminates this token: + */ + break; + } + + ADD_TO_TOKEN_BUFFER(stream_tokenizer, c); + + ++bytes_in_use; + --bytes_available; + + c = _GetNextChar(stream_tokenizer); + } + + ADD_TO_TOKEN_BUFFER(stream_tokenizer, '\0'); + + *destination = stream_tokenizer->token_buffer; + + return SDP_SUCCESS; +} + + + + + +void SDP_DestroyStreamTokenizer(SDP_StreamTokenizer *stream_tokenizer) +{ + SDP_AssertNotNull(stream_tokenizer); + + if (stream_tokenizer->token_buffer) + SDP_Destroy(stream_tokenizer->token_buffer); + + SDP_Destroy(stream_tokenizer); +} + + + + + +/******************************************************************************* + * + * Name + * _GrowTokenBuffer(stream_tokenizer) + * + * Purpose + * This function tries to grow the token buffer, doubling it in + * size. It returns true if it successfully grows the token + * buffer, false if memory reallocation fails. + * + * Parameters + * tokenizer - A pointer to the SDP_StreamTokenizer struct to grow + * the token buffer of. + * + */ +static int _GrowTokenBuffer(SDP_StreamTokenizer *stream_tokenizer) +{ + size_t bytes_to_reallocate; + char *larger_token_buffer; + + bytes_to_reallocate = stream_tokenizer->token_buffer_size * 2; + larger_token_buffer = (char *) SDP_Reallocate( + stream_tokenizer->token_buffer, bytes_to_reallocate + ); + if (larger_token_buffer == NULL) + return SDP_FAILURE; + + stream_tokenizer->token_buffer = larger_token_buffer; + stream_tokenizer->token_buffer_size = bytes_to_reallocate; + + return SDP_SUCCESS; +} + + + + + +/******************************************************************************* + * + * Name + * _GetNextChar(stream_tokenizer) + * + * Purpose + * This function gets the next character from the stream and + * returns it. It returns '\0' when the stream is exausted of all + * of its characters. + * + * Parameters + * tokenizer - A pointer to the SDP_StreamTokenizer struct. + * + */ +static char _GetNextChar(SDP_StreamTokenizer *stream_tokenizer) +{ + /* "int", because fgetc() returns -1 for EOF: */ + int c; + + switch (stream_tokenizer->stream_type) + { + case SDP_CHARACTER_STREAM: + c = *(stream_tokenizer->stream.character); + + /* + * Only move on to the next char if it isn't NULL, + * otherwise it just saty at this point: + */ + if (c) + ++stream_tokenizer->stream.character; + + break; + case SDP_FILE_STREAM: + c = fgetc(stream_tokenizer->stream.file); + + /* Same thing as above: */ + if (c == EOF) + c = '\0'; + + break; + default: + SDP_AssertionFailed("Bad stream type."); + break; + } + + return((char) c); +} + + + + +/******************************************************************************* + * + * Name + * _UngetNextChar(stream_tokenizer, c) + * + * Purpose + * This function puts the last character back onto the stream if + * you're not ready for it yet. + * + * Parameters + * tokenizer - A pointer to the SDP_StreamTokenizer struct. + * c - The character to put back in the stream (ignored + * for some types of streams). + * + */ +static void _UngetNextChar( + SDP_StreamTokenizer * stream_tokenizer, + char c) +{ + switch (stream_tokenizer->stream_type) + { + case SDP_CHARACTER_STREAM: + --stream_tokenizer->stream.character; + break; + case SDP_FILE_STREAM: + ungetc(c, stream_tokenizer->stream.file); + break; + default: + SDP_AssertionFailed("Bad stream type."); + break; + } +} diff --git a/src/sdp_lib/src/SDP_StreamTokenizer.h b/src/sdp_lib/src/SDP_StreamTokenizer.h new file mode 100644 index 0000000..b2c6f50 --- /dev/null +++ b/src/sdp_lib/src/SDP_StreamTokenizer.h @@ -0,0 +1,81 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SDP_STREAM_TOKENIZER_INCLUDED +#define SDP_STREAM_TOKENIZER_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + + + +typedef struct { + /* The type of stream we're reading from: */ + enum { + SDP_CHARACTER_STREAM, + SDP_FILE_STREAM + } stream_type; + + /* + * This stores the source of the stream we'll read from to get each + * token: + */ + union { + char *character; + FILE *file; + } stream; + + /* + * This stores a dynamically allocated buffer that contains each + * token one at a time: + */ + char *token_buffer; + + /* The size in bytes of the currently allocated token buffer: */ + size_t token_buffer_size; + + /* A pointer to the current position within token_buffer: */ + char *token_buffer_ptr; +} SDP_StreamTokenizer; + + + +extern SDP_StreamTokenizer *SDP_NewStreamTokenizer(void); + +extern void SDP_UseStringAsStream( + SDP_StreamTokenizer * stream_tokenizer, + const char * stream +); +extern void SDP_UseFileAsStream( + SDP_StreamTokenizer * stream_tokenizer, + FILE * stream +); +extern int SDP_GetNextToken( + SDP_StreamTokenizer * stream_tokenizer, + char ** destination +); + +extern void SDP_DestroyStreamTokenizer(SDP_StreamTokenizer *stream_tokenizer); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdp_lib/src/SDP_Utility.c b/src/sdp_lib/src/SDP_Utility.c new file mode 100644 index 0000000..68c05bb --- /dev/null +++ b/src/sdp_lib/src/SDP_Utility.c @@ -0,0 +1,114 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#include +#include +#include +#include +#include "SDP_Utility.h" + + + + + + + +/* The array to contain pointers to descriptions for all standardized types: */ +static char *_type_description_table[256]; + +/* + * Has the array been filled with pointers to strings containing descriptions + * yet? + */ +static int _type_table_initialized = 0; + +/* The function used to fill the array: */ +static void _InitializeFieldTypeArray(void); + +int SDP_IsKnownFieldType(char type) +{ + SDP_Assert(type >= 0); + + _InitializeFieldTypeArray(); + if (_type_description_table[(unsigned char) type]) + return 1; + else + return 0; +} + + + + + +char *SDP_GetFieldTypeDescription(char type) +{ + SDP_Assert(type >= 0); + + _InitializeFieldTypeArray(); + + return _type_description_table[(unsigned char) type]; +} + + + + + +void SDP_AssertionFailed( + const char *format, + ...) +{ + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + + exit(0); +} + + + + + +static void _InitializeFieldTypeArray(void) +{ + if (_type_table_initialized) + return; + + /* Initialze each type to a NULL pointer... */ + memset(_type_description_table, 0, sizeof(_type_description_table)); + + /* + * ...then replace the NULL pointers with pointers to strings + * describing the types we recognize: + */ + _type_description_table['v'] = "protocol version field"; + _type_description_table['o'] = "owner/origin field"; + _type_description_table['s'] = "session name field"; + _type_description_table['i'] = "session or media description field"; + _type_description_table['u'] = "URI field"; + _type_description_table['e'] = "email address field"; + _type_description_table['p'] = "phone number field"; + _type_description_table['c'] = "session or media connection data field"; + _type_description_table['b'] = "session or media bandwidth " + "information field"; + _type_description_table['t'] = "session start/stop time field"; + _type_description_table['r'] = "repeat interval field"; + _type_description_table['z'] = "timezone adjustments field"; + _type_description_table['e'] = "encryption information field"; + _type_description_table['a'] = "session or media attribute field"; + _type_description_table['m'] = "media description field"; + + _type_table_initialized = 1; +} diff --git a/src/sdp_lib/src/SDP_Utility.h b/src/sdp_lib/src/SDP_Utility.h new file mode 100755 index 0000000..ee83c1d --- /dev/null +++ b/src/sdp_lib/src/SDP_Utility.h @@ -0,0 +1,135 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SDP_UTILITY_INCLUDED +#define SDP_UTILITY_INCLUDED + +#ifdef __cplusplus +extern "C" { +#endif + +#include + + +#if defined WIN32 +#define snprintf _snprintf +#define vsnprintf _vsnprintf +#endif + +/* + * The first two macros are used as return values, and the second two are used + * to test a return value: + */ +#define SDP_FAILURE 0 +#define SDP_SUCCESS 1 +#define SDP_FAILED(_rv_) ((_rv_) ? 0 : 1) +#define SDP_SUCCEEDED(_rv_) (SDP_FAILED(_rv_) ? 0 : 1) + +/* Are we on Windows? */ +#if (defined(__WIN32__) || defined(__WIN32) || defined(__WIN32)) +# define SDP_ON_WINDOWS +#endif + +/* + * Simple named wrappers around malloc(), realloc() and free(). Feel free to + * change the replacements with what ever routines you like (for example, the + * Win32 API GetProcHeap()/HeapAlloc(), HeapReAlloc(), and HeapFree() + * combination): + */ +#define SDP_Allocate(_bytes_) malloc(_bytes_) +#define SDP_Reallocate(_memory_, _bytes_) realloc(_memory_, _bytes_) +#define SDP_Destroy(_memory_) free(_memory_) + +/* + * SinisterSdp uses these assertion macros to ensure things that should never + * happen, don't happen. If you don't want the added weight in compiled code + * these statements will add, then define SINISTERSDP_NO_ASSERTIONS when + * building: + */ +#ifdef SINISTERSDP_NO_ASSERTIONS +# define SDP_Assert(_expr_) +# define SDP_AssertNull(_expr_) +# define SDP_AssertNotNull(_expr_) +# define SDP_AssertTrue(_expr_) +# define SDP_AssertFalse(_expr_) +#else +# define SDP_Assert(_expr_) \ + ((!(_expr_)) \ + ? SDP_AssertionFailed( \ + "Assertion \"%s\" failed. (Assertion failed " \ + "at line %d from %s.", \ + #_expr_, \ + __LINE__, \ + __FILE__ \ + ) \ + : (void) 0) +# define SDP_AssertNull(_expr_) \ + ((_expr_) \ + ? SDP_AssertionFailed( \ + "\"%s\" should be NULL, but it isn't. " \ + "(Assertion failed at line %d from %s.)", \ + #_expr_, \ + __LINE__, \ + __FILE__ \ + ) \ + : (void) 0) +# define SDP_AssertNotNull(_expr_) \ + ((_expr_ == NULL) \ + ? SDP_AssertionFailed( \ + "\"%s\" is NULL, and it shouldn't be. " \ + "(Assertion failed at line %d from %s.)", \ + #_expr_, \ + __LINE__, \ + __FILE__ \ + ) \ + : (void) 0) +# define SDP_AssertTrue(_expr_) \ + ((!(_expr_)) \ + ? SDP_AssertionFailed( \ + "\"%s\" is false; it should be true. " \ + "(Assertion failed at line %d from %s.)", \ + #_expr_, \ + __LINE__, \ + __FILE__ \ + ) \ + : (void) 0) +# define SDP_AssertFalse(_expr_) \ + ((_expr_) \ + ? SDP_AssertionFailed( \ + "\"%s\" is ture; it should be false. " \ + "(Assertion failed at line %d from %s.", \ + #_expr_, \ + __LINE__, \ + __FILE__ \ + ) \ + : (void) 0) +#endif + +/* Return value macros for handlers: */ +#define SDP_CONTINUE_AFTER_ERROR 1; +#define SDP_STOP_AFTER_ERROR 0; + + + +extern void SDP_AssertionFailed(const char *format, ...); +extern int SDP_IsKnownFieldType(char type); +extern char *SDP_GetFieldTypeDescription(char type); + + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/sdp_lib/src/SinisterSdp.h b/src/sdp_lib/src/SinisterSdp.h new file mode 100644 index 0000000..c830139 --- /dev/null +++ b/src/sdp_lib/src/SinisterSdp.h @@ -0,0 +1,26 @@ +/******************************************************************************* + * + * Copyright 2004 by William G. Davis. + * + * This library is free software released under the terms of the GNU Lesser + * General Public License (LGPL), the full terms of which can be found in the + * "COPYING" file that comes with the distribution. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. + * + ******************************************************************************/ + +#ifndef SINISTERSDP_INCLUDED +#define SINISTERSDP_INCLUDED + +#include "SDP/SDP_Parser" +#include "SDP/SDP_Generator" + +#define SINISTERSDP_VERSION "0.80" +#define SINISTERSDP_DATE_RELEASED "Fri Oct 15 04:21:54 2004" +#define SINISTERSDP_AUTHOR_OF_RELEASE \ + "William G. Davis " + +#endif